9 Commits

Author SHA1 Message Date
Codex a8d16f918c Fix monero_c Gitea workflow regressions
build / peya x86_64 Linux (push) Successful in 13m19s
build / peya Win64 (push) Successful in 14m47s
consistency / checksum sync (push) Successful in 6s
consistency / Dart bindings sync (push) Failing after 2m18s
2026-04-09 12:29:46 +02:00
Codex ddd7d5edea Harden Gitea workflows for monero_c releases
build / peya x86_64 Linux (push) Failing after 7m26s
build / peya Win64 (push) Successful in 14m32s
consistency / checksum sync (push) Failing after 7s
consistency / Dart bindings sync (push) Failing after 14s
2026-04-09 11:41:20 +02:00
Codex 5e90cedb27 Update Peya submodule for release fixes 2026-04-08 21:52:56 +02:00
Codex b506d2a8ee Add Gitea workflows for monero_c builds
consistency / checksum sync (push) Successful in 6s
consistency / Dart bindings sync (push) Failing after 9s
build / peya x86_64 Linux (push) Failing after 7s
build / peya Win64 (push) Failing after 7s
2026-04-08 21:52:09 +02:00
Codex d701dd10d3 Fix coin-specific Dart wallet bindings
Check if checksums are in sync / android (push) Failing after 15s
Check if dart bindings are in sync / android (push) Failing after 15s
Build documentation / build (push) Failing after 13s
full compatibility check / lib_mingw (peya) (push) Has been cancelled
full compatibility check / lib_mingw (salvium) (push) Has been cancelled
full compatibility check / lib_android (monero) (push) Has been cancelled
full compatibility check / lib_android (peya) (push) Has been cancelled
full compatibility check / lib_android (salvium) (push) Has been cancelled
full compatibility check / lib_linux (monero) (push) Has been cancelled
full compatibility check / lib_linux (peya) (push) Has been cancelled
full compatibility check / lib_linux (salvium) (push) Has been cancelled
full compatibility check / macos build (monero) (push) Has been cancelled
full compatibility check / macos build (peya) (push) Has been cancelled
full compatibility check / macos build (salvium) (push) Has been cancelled
full compatibility check / ios build (monero) (push) Has been cancelled
full compatibility check / ios build (peya) (push) Has been cancelled
full compatibility check / ios build (salvium) (push) Has been cancelled
full compatibility check / create single release file (push) Has been cancelled
full compatibility check / test ts library (push) Has been cancelled
full compatibility check / linux regression tests (monero) (push) Has been cancelled
full compatibility check / linux regression tests (peya) (push) Has been cancelled
full compatibility check / linux regression tests (salvium) (push) Has been cancelled
full compatibility check / macos regression tests (monero) (push) Has been cancelled
full compatibility check / macos regression tests (peya) (push) Has been cancelled
full compatibility check / macos regression tests (salvium) (push) Has been cancelled
full compatibility check / linux integration tests (monero) (push) Has been cancelled
full compatibility check / lib_mingw (monero) (push) Has been cancelled
full compatibility check / linux integration tests (peya) (push) Has been cancelled
full compatibility check / linux integration tests (salvium) (push) Has been cancelled
full compatibility check / macos integration tests (monero) (push) Has been cancelled
full compatibility check / macos integration tests (peya) (push) Has been cancelled
full compatibility check / macos integration tests (salvium) (push) Has been cancelled
full compatibility check / comment on pr (push) Has been cancelled
2026-04-08 19:47:55 +02:00
Codex 5635ca4db0 Fix MinGW boost log build for Windows DLL
Check if checksums are in sync / android (push) Failing after 1m4s
Check if dart bindings are in sync / android (push) Failing after 14s
Build documentation / build (push) Failing after 14s
full compatibility check / lib_mingw (monero) (push) Failing after 1m29s
full compatibility check / lib_mingw (peya) (push) Failing after 1m14s
full compatibility check / lib_mingw (salvium) (push) Failing after 1m14s
full compatibility check / lib_android (monero) (push) Failing after 56s
full compatibility check / lib_android (salvium) (push) Has been cancelled
full compatibility check / lib_linux (monero) (push) Has been cancelled
full compatibility check / lib_linux (peya) (push) Has been cancelled
full compatibility check / lib_linux (salvium) (push) Has been cancelled
full compatibility check / macos build (monero) (push) Has been cancelled
full compatibility check / macos build (peya) (push) Has been cancelled
full compatibility check / macos build (salvium) (push) Has been cancelled
full compatibility check / ios build (monero) (push) Has been cancelled
full compatibility check / ios build (peya) (push) Has been cancelled
full compatibility check / ios build (salvium) (push) Has been cancelled
full compatibility check / create single release file (push) Has been cancelled
full compatibility check / test ts library (push) Has been cancelled
full compatibility check / linux regression tests (monero) (push) Has been cancelled
full compatibility check / lib_android (peya) (push) Has been cancelled
full compatibility check / linux regression tests (peya) (push) Has been cancelled
full compatibility check / linux regression tests (salvium) (push) Has been cancelled
full compatibility check / macos regression tests (monero) (push) Has been cancelled
full compatibility check / macos regression tests (peya) (push) Has been cancelled
full compatibility check / macos regression tests (salvium) (push) Has been cancelled
full compatibility check / linux integration tests (monero) (push) Has been cancelled
full compatibility check / linux integration tests (peya) (push) Has been cancelled
full compatibility check / linux integration tests (salvium) (push) Has been cancelled
full compatibility check / macos integration tests (monero) (push) Has been cancelled
full compatibility check / macos integration tests (peya) (push) Has been cancelled
full compatibility check / macos integration tests (salvium) (push) Has been cancelled
full compatibility check / comment on pr (push) Has been cancelled
2026-04-08 17:42:01 +02:00
Codex c3474df916 Sync salvium and peya tx info bindings
full compatibility check / lib_mingw (monero) (push) Has been cancelled
full compatibility check / lib_mingw (peya) (push) Has been cancelled
full compatibility check / lib_mingw (salvium) (push) Has been cancelled
full compatibility check / lib_android (monero) (push) Has been cancelled
full compatibility check / lib_android (peya) (push) Has been cancelled
full compatibility check / lib_android (salvium) (push) Has been cancelled
full compatibility check / lib_linux (monero) (push) Has been cancelled
full compatibility check / lib_linux (peya) (push) Has been cancelled
full compatibility check / lib_linux (salvium) (push) Has been cancelled
full compatibility check / macos build (monero) (push) Has been cancelled
full compatibility check / macos build (peya) (push) Has been cancelled
full compatibility check / macos build (salvium) (push) Has been cancelled
full compatibility check / ios build (monero) (push) Has been cancelled
full compatibility check / ios build (peya) (push) Has been cancelled
full compatibility check / ios build (salvium) (push) Has been cancelled
full compatibility check / create single release file (push) Has been cancelled
full compatibility check / test ts library (push) Has been cancelled
full compatibility check / linux regression tests (monero) (push) Has been cancelled
full compatibility check / linux regression tests (peya) (push) Has been cancelled
full compatibility check / linux regression tests (salvium) (push) Has been cancelled
full compatibility check / macos regression tests (monero) (push) Has been cancelled
full compatibility check / macos regression tests (peya) (push) Has been cancelled
full compatibility check / macos regression tests (salvium) (push) Has been cancelled
full compatibility check / linux integration tests (monero) (push) Has been cancelled
full compatibility check / linux integration tests (peya) (push) Has been cancelled
full compatibility check / linux integration tests (salvium) (push) Has been cancelled
full compatibility check / macos integration tests (monero) (push) Has been cancelled
full compatibility check / macos integration tests (peya) (push) Has been cancelled
full compatibility check / macos integration tests (salvium) (push) Has been cancelled
full compatibility check / comment on pr (push) Has been cancelled
Build documentation / build (push) Has been cancelled
Check if dart bindings are in sync / android (push) Has been cancelled
Check if checksums are in sync / android (push) Has been cancelled
2026-04-06 18:45:39 +02:00
Codex 1af4416964 Fix peya build and update patched submodules
Check if checksums are in sync / android (push) Failing after 18s
Check if dart bindings are in sync / android (push) Failing after 17s
Build documentation / build (push) Failing after 31s
full compatibility check / lib_mingw (monero) (push) Failing after 1m48s
full compatibility check / lib_mingw (peya) (push) Failing after 1m13s
full compatibility check / lib_mingw (salvium) (push) Failing after 1m13s
full compatibility check / lib_android (monero) (push) Failing after 51s
full compatibility check / lib_android (peya) (push) Has started running
full compatibility check / lib_android (salvium) (push) Has been cancelled
full compatibility check / lib_linux (monero) (push) Has been cancelled
full compatibility check / lib_linux (peya) (push) Has been cancelled
full compatibility check / lib_linux (salvium) (push) Has been cancelled
full compatibility check / macos build (monero) (push) Has been cancelled
full compatibility check / macos build (peya) (push) Has been cancelled
full compatibility check / macos build (salvium) (push) Has been cancelled
full compatibility check / ios build (monero) (push) Has been cancelled
full compatibility check / ios build (peya) (push) Has been cancelled
full compatibility check / ios build (salvium) (push) Has been cancelled
full compatibility check / create single release file (push) Has been cancelled
full compatibility check / test ts library (push) Has been cancelled
full compatibility check / linux regression tests (monero) (push) Has been cancelled
full compatibility check / linux regression tests (peya) (push) Has been cancelled
full compatibility check / linux regression tests (salvium) (push) Has been cancelled
full compatibility check / macos regression tests (monero) (push) Has been cancelled
full compatibility check / macos regression tests (peya) (push) Has been cancelled
full compatibility check / macos regression tests (salvium) (push) Has been cancelled
full compatibility check / linux integration tests (monero) (push) Has been cancelled
full compatibility check / linux integration tests (peya) (push) Has been cancelled
full compatibility check / linux integration tests (salvium) (push) Has been cancelled
full compatibility check / macos integration tests (monero) (push) Has been cancelled
full compatibility check / macos integration tests (peya) (push) Has been cancelled
full compatibility check / macos integration tests (salvium) (push) Has been cancelled
full compatibility check / comment on pr (push) Has been cancelled
2026-04-06 16:31:25 +02:00
Codex 0d753a0d79 Add salvium and peya support to monero_c
Check if checksums are in sync / android (push) Failing after 1m42s
Check if dart bindings are in sync / android (push) Failing after 16s
Build documentation / build (push) Has been cancelled
full compatibility check / lib_mingw (monero) (push) Has been cancelled
full compatibility check / lib_mingw (peya) (push) Has been cancelled
full compatibility check / lib_mingw (salvium) (push) Has been cancelled
full compatibility check / lib_android (monero) (push) Has been cancelled
full compatibility check / lib_android (peya) (push) Has been cancelled
full compatibility check / lib_android (salvium) (push) Has been cancelled
full compatibility check / lib_linux (monero) (push) Has been cancelled
full compatibility check / lib_linux (peya) (push) Has been cancelled
full compatibility check / lib_linux (salvium) (push) Has been cancelled
full compatibility check / macos build (monero) (push) Has been cancelled
full compatibility check / macos build (peya) (push) Has been cancelled
full compatibility check / macos build (salvium) (push) Has been cancelled
full compatibility check / ios build (monero) (push) Has been cancelled
full compatibility check / ios build (peya) (push) Has been cancelled
full compatibility check / ios build (salvium) (push) Has been cancelled
full compatibility check / create single release file (push) Has been cancelled
full compatibility check / test ts library (push) Has been cancelled
full compatibility check / linux regression tests (monero) (push) Has been cancelled
full compatibility check / linux regression tests (peya) (push) Has been cancelled
full compatibility check / linux regression tests (salvium) (push) Has been cancelled
full compatibility check / macos regression tests (monero) (push) Has been cancelled
full compatibility check / macos regression tests (peya) (push) Has been cancelled
full compatibility check / macos regression tests (salvium) (push) Has been cancelled
full compatibility check / linux integration tests (monero) (push) Has been cancelled
full compatibility check / linux integration tests (peya) (push) Has been cancelled
full compatibility check / linux integration tests (salvium) (push) Has been cancelled
full compatibility check / macos integration tests (monero) (push) Has been cancelled
full compatibility check / macos integration tests (peya) (push) Has been cancelled
full compatibility check / macos integration tests (salvium) (push) Has been cancelled
full compatibility check / comment on pr (push) Has been cancelled
2026-04-06 14:38:17 +02:00
149 changed files with 35758 additions and 18070 deletions
+105
View File
@@ -0,0 +1,105 @@
name: build
run-name: build ${{ inputs.flavor || 'peya' }}
on:
workflow_dispatch:
inputs:
flavor:
description: monero_c flavor to build
required: true
default: peya
type: choice
options:
- peya
- salvium
- monero
push:
branches:
- develop
- main
paths:
- ".gitea/workflows/build.yml"
- "build_single.sh"
- "apply_patches.sh"
- "contrib/depends/**"
- "patches/**"
- "monero_libwallet2_api_c/**"
- "salvium_libwallet2_api_c/**"
- "peya_libwallet2_api_c/**"
- "impls/monero.dart/**"
- "impls/monero.ts/**"
- ".gitmodules"
jobs:
build-libs:
name: ${{ inputs.flavor || 'peya' }} ${{ matrix.target.name }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- name: x86_64 Linux
host: x86_64-linux-gnu
packages: automake autotools-dev build-essential ca-certificates ccache clang cmake curl git gperf libssl-dev libtool pkg-config python3
- name: Win64
host: x86_64-w64-mingw32
packages: automake autotools-dev build-essential ca-certificates ccache clang cmake curl git libssl-dev libtool pkg-config python3 gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64
env:
FLAVOR: ${{ inputs.flavor || 'peya' }}
steps:
- name: Checkout
uses: https://github.com/actions/checkout@v4
with:
fetch-depth: 1
submodules: false
- name: Configure Gitea auth for private submodules
env:
MONERO_C_GITEA_PAT: ${{ secrets.MONERO_C_GITEA_PAT }}
PEYA_GITEA_PAT: ${{ secrets.PEYA_GITEA_PAT }}
GITEA_PAT: ${{ secrets.GITEA_PAT }}
run: |
set -euo pipefail
AUTH_TOKEN="${MONERO_C_GITEA_PAT:-${PEYA_GITEA_PAT:-${GITEA_PAT:-}}}"
if [ "${FLAVOR}" != "monero" ] && [ -z "${AUTH_TOKEN}" ]; then
echo "Missing Gitea PAT secret for private ${FLAVOR} submodule"
exit 1
fi
if [ -n "${AUTH_TOKEN}" ]; then
git config --global url."http://tiamak:${AUTH_TOKEN}@54.38.205.168:3000/".insteadOf "http://54.38.205.168:3000/"
fi
git submodule sync
git -c protocol.version=2 submodule update --init --force "${FLAVOR}"
git -C "${FLAVOR}" submodule sync --recursive
git -C "${FLAVOR}" -c protocol.version=2 submodule update --init --force --recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.target.packages }}
- name: Prepare MinGW alternatives
if: ${{ matrix.target.host == 'x86_64-w64-mingw32' }}
run: |
sudo update-alternatives --set x86_64-w64-mingw32-g++ "$(which x86_64-w64-mingw32-g++-posix)"
sudo update-alternatives --set x86_64-w64-mingw32-gcc "$(which x86_64-w64-mingw32-gcc-posix)"
- name: Apply patches
run: |
./apply_patches.sh "${FLAVOR}"
- name: Build libraries
run: |
./build_single.sh "${FLAVOR}" "${{ matrix.target.host }}" -j"$(nproc)"
- name: Upload build artifacts
uses: https://github.com/actions/upload-artifact@v3
with:
name: monero-c-${{ env.FLAVOR }}-${{ matrix.target.host }}
path: release/${{ env.FLAVOR }}/${{ matrix.target.host }}_*.xz
if-no-files-found: error
+65
View File
@@ -0,0 +1,65 @@
name: consistency
on:
workflow_dispatch:
push:
branches:
- develop
- main
paths:
- ".gitea/workflows/consistency.yml"
- "generate_checksum.sh"
- "impls/monero.dart/**"
- "impls/monero.ts/**"
- "monero_libwallet2_api_c/**"
- "salvium_libwallet2_api_c/**"
- "peya_libwallet2_api_c/**"
- ".gitmodules"
jobs:
checksums:
name: checksum sync
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: https://github.com/actions/checkout@v4
with:
fetch-depth: 1
submodules: false
- name: Generate checksums
run: |
./generate_checksum.sh
- name: Check for dirty tree
run: |
git diff --exit-code
dart-bindings:
name: Dart bindings sync
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: https://github.com/actions/checkout@v4
with:
fetch-depth: 1
submodules: false
- name: Setup Flutter
uses: https://github.com/subosito/flutter-action@v2
with:
channel: stable
- name: Fetch Dart dependencies
run: |
cd impls/monero.dart
dart pub get
- name: Regenerate Dart bindings
run: |
cd impls/monero.dart
./update_bindings.sh
- name: Check for dirty tree
run: |
git diff --exit-code
+243
View File
@@ -0,0 +1,243 @@
name: release
run-name: release ${{ inputs.flavor }} ${{ inputs.tag_name }}
on:
workflow_dispatch:
inputs:
tag_name:
description: Release tag (for example v0.1.0)
required: true
flavor:
description: monero_c flavor to build
required: true
default: peya
type: choice
options:
- peya
- salvium
- monero
target_ref:
description: Branch, tag or commit to build and tag
required: true
default: develop
release_name:
description: Optional release title
required: false
release_notes:
description: Release notes / body
required: false
prerelease:
description: Mark release as prerelease
required: false
default: false
type: boolean
draft:
description: Create release as draft
required: false
default: false
type: boolean
jobs:
create-release:
name: Create release
runs-on: ubuntu-latest
outputs:
release_id: ${{ steps.release.outputs.release_id }}
flavor: ${{ inputs.flavor }}
steps:
- name: Install release tooling
run: |
sudo apt-get update
sudo apt-get install -y curl jq
- name: Create or reuse Gitea release
id: release
env:
MONERO_C_GITEA_PAT: ${{ secrets.MONERO_C_GITEA_PAT }}
PEYA_GITEA_PAT: ${{ secrets.PEYA_GITEA_PAT }}
GITEA_PAT: ${{ secrets.GITEA_PAT }}
GITEA_API: ${{ github.server_url }}/api/v1
REPO: ${{ github.repository }}
TAG_NAME: ${{ inputs.tag_name }}
INPUT_RELEASE_NAME: ${{ inputs.release_name }}
RELEASE_NOTES: ${{ inputs.release_notes }}
TARGET_COMMITISH: ${{ inputs.target_ref }}
INPUT_PRERELEASE: ${{ inputs.prerelease }}
INPUT_DRAFT: ${{ inputs.draft }}
run: |
set -euo pipefail
GITEA_TOKEN="${MONERO_C_GITEA_PAT:-${PEYA_GITEA_PAT:-${GITEA_PAT:-}}}"
if [ -z "${GITEA_TOKEN}" ]; then
echo "Missing Gitea PAT secret for release publishing"
exit 1
fi
if [ -n "${INPUT_RELEASE_NAME}" ]; then
RELEASE_NAME="${INPUT_RELEASE_NAME}"
else
RELEASE_NAME="Release ${TAG_NAME}"
fi
get_release_url="${GITEA_API}/repos/${REPO}/releases/tags/${TAG_NAME}"
create_release_url="${GITEA_API}/repos/${REPO}/releases"
status="$(curl -sS -o /tmp/release.json -w '%{http_code}' \
-H "Authorization: token ${GITEA_TOKEN}" \
"${get_release_url}")"
if [ "${status}" = "200" ]; then
echo "release_id=$(jq -r '.id' /tmp/release.json)" >> "$GITHUB_OUTPUT"
exit 0
fi
if [ "${status}" != "404" ]; then
echo "Unexpected response while checking release: HTTP ${status}"
cat /tmp/release.json
exit 1
fi
jq -n \
--arg tag_name "${TAG_NAME}" \
--arg target_commitish "${TARGET_COMMITISH}" \
--arg name "${RELEASE_NAME}" \
--arg body "${RELEASE_NOTES}" \
--argjson draft "${INPUT_DRAFT}" \
--argjson prerelease "${INPUT_PRERELEASE}" \
'{tag_name:$tag_name,target_commitish:$target_commitish,name:$name,body:$body,draft:$draft,prerelease:$prerelease}' \
> /tmp/release-payload.json
curl -sS \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-X POST \
--data @/tmp/release-payload.json \
"${create_release_url}" \
-o /tmp/release.json
if ! jq -e '.id' /tmp/release.json >/dev/null; then
cat /tmp/release.json
exit 1
fi
echo "release_id=$(jq -r '.id' /tmp/release.json)" >> "$GITHUB_OUTPUT"
build-release:
name: ${{ matrix.target.name }}
needs: create-release
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
target:
- name: x86_64 Linux
host: x86_64-linux-gnu
packages: automake autotools-dev build-essential ca-certificates ccache clang cmake curl git gperf libssl-dev libtool pkg-config python3
- name: Win64
host: x86_64-w64-mingw32
packages: automake autotools-dev build-essential ca-certificates ccache clang cmake curl git libssl-dev libtool pkg-config python3 gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64
steps:
- name: Checkout
uses: https://github.com/actions/checkout@v4
with:
fetch-depth: 1
submodules: false
ref: ${{ inputs.target_ref }}
- name: Configure Gitea auth for private submodules
env:
MONERO_C_GITEA_PAT: ${{ secrets.MONERO_C_GITEA_PAT }}
PEYA_GITEA_PAT: ${{ secrets.PEYA_GITEA_PAT }}
GITEA_PAT: ${{ secrets.GITEA_PAT }}
FLAVOR: ${{ needs.create-release.outputs.flavor }}
run: |
set -euo pipefail
AUTH_TOKEN="${MONERO_C_GITEA_PAT:-${PEYA_GITEA_PAT:-${GITEA_PAT:-}}}"
if [ "${FLAVOR}" != "monero" ] && [ -z "${AUTH_TOKEN}" ]; then
echo "Missing Gitea PAT secret for private ${FLAVOR} submodule"
exit 1
fi
if [ -n "${AUTH_TOKEN}" ]; then
git config --global url."http://tiamak:${AUTH_TOKEN}@54.38.205.168:3000/".insteadOf "http://54.38.205.168:3000/"
fi
git submodule sync
git -c protocol.version=2 submodule update --init --force "${FLAVOR}"
git -C "${FLAVOR}" submodule sync --recursive
git -C "${FLAVOR}" -c protocol.version=2 submodule update --init --force --recursive
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.target.packages }}
- name: Prepare MinGW alternatives
if: ${{ matrix.target.host == 'x86_64-w64-mingw32' }}
run: |
sudo update-alternatives --set x86_64-w64-mingw32-g++ "$(which x86_64-w64-mingw32-g++-posix)"
sudo update-alternatives --set x86_64-w64-mingw32-gcc "$(which x86_64-w64-mingw32-gcc-posix)"
- name: Apply patches
run: |
./apply_patches.sh "${{ needs.create-release.outputs.flavor }}"
- name: Build release libraries
run: |
./build_single.sh "${{ needs.create-release.outputs.flavor }}" "${{ matrix.target.host }}" -j"$(nproc)"
- name: Upload release assets
env:
MONERO_C_GITEA_PAT: ${{ secrets.MONERO_C_GITEA_PAT }}
PEYA_GITEA_PAT: ${{ secrets.PEYA_GITEA_PAT }}
GITEA_PAT: ${{ secrets.GITEA_PAT }}
GITEA_API: ${{ github.server_url }}/api/v1
REPO: ${{ github.repository }}
RELEASE_ID: ${{ needs.create-release.outputs.release_id }}
FLAVOR: ${{ needs.create-release.outputs.flavor }}
HOST: ${{ matrix.target.host }}
run: |
set -euo pipefail
GITEA_TOKEN="${MONERO_C_GITEA_PAT:-${PEYA_GITEA_PAT:-${GITEA_PAT:-}}}"
if [ -z "${GITEA_TOKEN}" ]; then
echo "Missing Gitea PAT secret for release publishing"
exit 1
fi
assets_url="${GITEA_API}/repos/${REPO}/releases/${RELEASE_ID}/assets"
shopt -s nullglob
files=(release/${FLAVOR}/${HOST}_*.xz)
if [ "${#files[@]}" -eq 0 ]; then
echo "No release assets found in release/${FLAVOR} for ${HOST}"
exit 1
fi
curl -sS \
-H "Authorization: token ${GITEA_TOKEN}" \
"${assets_url}" \
-o /tmp/release-assets.json
for asset in "${files[@]}"; do
asset_name="$(basename "${asset}")"
existing_id="$(jq -r --arg name "${asset_name}" '.[] | select(.name == $name) | .id' /tmp/release-assets.json | head -n 1)"
if [ -n "${existing_id}" ]; then
curl -sS \
-H "Authorization: token ${GITEA_TOKEN}" \
-X DELETE \
"${assets_url}/${existing_id}" \
>/dev/null
fi
curl -sS \
-H "Authorization: token ${GITEA_TOKEN}" \
-X POST \
-F "attachment=@${asset}" \
"${assets_url}?name=${asset_name}" \
>/dev/null
done
-56
View File
@@ -1,56 +0,0 @@
name: Check if checksums are in sync
on: [push]
permissions:
issues: write
pull-requests: write
jobs:
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: 8BitJonny/gh-get-current-pr@3.0.0
id: PR
- uses: subosito/flutter-action@v2
with:
channel: stable
- name: generate checksums
run: |
./generate_checksum.sh
- name: check if git tree is clean
run: |
if [ -z "$(git status --porcelain)" ]; then
exit 0
else
exit 1
fi
- uses: actions/github-script@v7
continue-on-error: true
id: get_issue_number
with:
script: |
if (context.issue.number) {
// Return issue number if present
return context.issue.number;
} else {
// Otherwise return issue number from commit
return (
await github.rest.repos.listPullRequestsAssociatedWithCommit({
commit_sha: context.sha,
owner: context.repo.owner,
repo: context.repo.repo,
})
).data[0].number;
}
result-encoding: string
- name: Create or update comment
continue-on-error: true
if: failure()
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{steps.get_issue_number.outputs.result}}
body: |
Invalid checksums, please run `./generate_checksum.sh`
-57
View File
@@ -1,57 +0,0 @@
name: Check if dart bindings are in sync
on: [push]
permissions:
issues: write
pull-requests: write
jobs:
android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: 8BitJonny/gh-get-current-pr@3.0.0
id: PR
- uses: subosito/flutter-action@v2
with:
channel: stable
- name: generate bindings
run: |
cd impls/monero.dart
./update_bindings.sh
- name: check if git tree is clean
run: |
if [ -z "$(git status --porcelain)" ]; then
exit 0
else
exit 1
fi
- uses: actions/github-script@v7
continue-on-error: true
id: get_issue_number
with:
script: |
if (context.issue.number) {
// Return issue number if present
return context.issue.number;
} else {
// Otherwise return issue number from commit
return (
await github.rest.repos.listPullRequestsAssociatedWithCommit({
commit_sha: context.sha,
owner: context.repo.owner,
repo: context.repo.repo,
})
).data[0].number;
}
result-encoding: string
- name: Create or update comment
continue-on-error: true
if: failure()
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{steps.get_issue_number.outputs.result}}
body: |
Invalid bindings found in monero.dart, make sure to run `./impls/monero.dart/update_bindings.sh`
-48
View File
@@ -1,48 +0,0 @@
name: Build documentation
on: [push]
env:
# Name of module and id separated by a slash
INSTANCE: Writerside/in
# Replace HI with the ID of the instance in capital letters
ARTIFACT: webHelpIN2-all.zip
# Docker image version
DOCKER_VERSION: "242.21870"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/setup-go@v5
with:
go-version: '^1.23.2'
- uses: hecrj/setup-rust-action@v2
with:
rust-version: stable
- name: Update image
run: cd docs && ./update_screenshot.sh
- name: Build Writerside docs using Docker
uses: JetBrains/writerside-github-action@v4
with:
location: "docs"
instance: ${{ env.INSTANCE }}
artifact: ${{ env.ARTIFACT }}
docker-version: ${{ env.DOCKER_VERSION }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: artifact
path: artifacts/${{ env.ARTIFACT }}
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: artifacts/${{ env.ARTIFACT }}
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
-598
View File
@@ -1,598 +0,0 @@
name: full compatibility check
on: [push]
permissions:
issues: write
pull-requests: write
jobs:
lib_mingw:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero]
runs-on: ubuntu-latest
container:
image: ubuntu:24.04
steps:
- name: Install dependencies
run: |
apt update
apt install -y pigz build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 gperf gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 gcc-mingw-w64-i686 g++-mingw-w64-i686
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Patch sources
run: |
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
- name: 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)
- name: rename artifacts
run: |
mkdir release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
done
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: release/gh/*
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: mingw ${{ matrix.coin }}
path: release/${{ matrix.coin }}
lib_android:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
runs-on: ubuntu-22.04
# container:
# image: debian:bookworm
steps:
- name: Free Disk Space
if: ${{ !startsWith(github.ref, 'refs/tags/v') }}
uses: jlumbroso/free-disk-space@main
with:
tool-cache: false
android: true
dotnet: true
haskell: true
large-packages: true
docker-images: true
swap-storage: true
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y llvm pigz build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 libtinfo6 gperf unzip python-is-python3
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Patch sources
run: |
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
- name: 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)
- name: rename artifacts
run: |
mkdir release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
done
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: release/gh/*
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: android ${{ matrix.coin }}
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]
runs-on: ubuntu-latest
container:
image: debian:bullseye
steps:
- name: Install dependencies
run: |
apt update
apt install -y pigz build-essential pkg-config autoconf libtool ccache make cmake gcc g++ git curl lbzip2 libtinfo5 gperf gcc-aarch64-linux-gnu g++-aarch64-linux-gnu gcc-i686-linux-gnu g++-i686-linux-gnu
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- name: Patch sources
run: |
git config --global --add safe.directory '*'
git config --global user.email "ci@mrcyjanek.net"
git config --global user.name "CI mrcyjanek.net"
./apply_patches.sh ${{ matrix.coin }}
- name: 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)
- name: rename artifacts
run: |
mkdir release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
done
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: release/gh/*
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: linux ${{ matrix.coin }}
path: release/${{ matrix.coin }}
lib_macos:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
name: macos build
runs-on: macos-14
steps:
- name: Checkout monero_c repo
uses: actions/checkout@v4
with:
repository: MrCyjaneK/monero_c
fetch-depth: 0
submodules: recursive
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '15.4'
- name: install dependencies
run: |
brew install 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 }}
- 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)
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)
- name: rename artifacts
run: |
mkdir release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
done
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: release/gh/*
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: macos ${{ matrix.coin }}
path: release/${{ matrix.coin }}
lib_ios:
strategy:
fail-fast: false
matrix:
coin: [monero, wownero, zano]
name: ios build
runs-on: macos-15
steps:
- name: Checkout monero_c repo
uses: actions/checkout@v4
with:
repository: MrCyjaneK/monero_c
fetch-depth: 0
submodules: recursive
- uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '16.1'
- name: install dependencies
run: |
brew install ccache cmake 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 }}
- 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)
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)
- name: rename artifacts
run: |
mkdir release/gh/
for i in release/${{ matrix.coin }}/*
do
cp "$i" "release/gh/${{ matrix.coin }}_$(basename $i)"
done
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: release/gh/*
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: ios ${{ matrix.coin }}
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
]
steps:
- uses: actions/download-artifact@v4
with:
name: android monero
path: release/monero
- uses: actions/download-artifact@v4
with:
name: android wownero
path: release/wownero
- uses: actions/download-artifact@v4
with:
name: android zano
path: release/zano
- uses: actions/download-artifact@v4
with:
name: ios monero
path: release/monero
- uses: actions/download-artifact@v4
with:
name: ios wownero
path: release/wownero
- uses: actions/download-artifact@v4
with:
name: ios zano
path: release/zano
- 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
- name: zip release dir
run: zip -r release-bundle.zip release
- name: Release
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
files: release-bundle.zip
token: ${{ secrets.CUSTOM_GITHUB_TOKEN }}
- name: Upload lib
uses: actions/upload-artifact@v4
with:
name: release-bulk
path: release
deno_monerots_test_linux:
name: test ts library
runs-on: ubuntu-24.04
needs: [
lib_linux
]
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: actions/download-artifact@v4
with:
name: linux monero
path: release/monero
- name: unpack and move monero_c
run: |
unxz -f -k release/*/*.xz
- uses: denoland/setup-deno@v1
with:
deno-version: vx.x.x
- name: Create symlink
run: |
cd impls/monero.ts
mkdir lib
cd lib
ln -s ../../../release/monero/x86_64-linux-gnu_libwallet2_api_c.so
mv x86_64-linux-gnu_libwallet2_api_c.so monero_libwallet2_api_c.so
cd ..
- name: Run tests
run: |
cd impls/monero.ts
deno run --unstable-ffi --allow-ffi checksum.ts
regression_tests_linux:
name: linux regression tests
strategy:
fail-fast: false
matrix:
coin: [monero, wownero]
needs: [
lib_linux
]
runs-on: ubuntu-24.04
steps:
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: actions/download-artifact@v4
with:
name: linux ${{ matrix.coin }}
path: release/${{ matrix.coin }}
- name: Run regression tests
run: COIN="${{ matrix.coin }}" deno test -A tests/regression.test.ts
regression_tests_macos:
name: macos regression tests
strategy:
matrix:
coin: [monero, wownero]
needs: [
lib_macos
]
runs-on: macos-14
steps:
- uses: denoland/setup-deno@v2
with:
deno-version: canary
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: actions/download-artifact@v4
with:
name: macos ${{ matrix.coin }}
path: release/${{ matrix.coin }}
- name: Run regression tests
run: COIN="${{ matrix.coin }}" deno test -A tests/regression.test.ts
integration_tests_linux:
name: linux integration tests
strategy:
matrix:
coin: [monero, wownero]
needs: [
lib_linux
]
runs-on: ubuntu-24.04
steps:
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: actions/download-artifact@v4
with:
name: linux ${{ matrix.coin }}
path: release/${{ matrix.coin }}
- name: Run integration tests
run: COIN="${{ matrix.coin }}" deno test -A tests/integration.test.ts
env:
SECRET_WALLET_PASSWORD: ${{ secrets.SECRET_WALLET_PASSWORD }}
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
steps:
- uses: denoland/setup-deno@v2
with:
deno-version: v2.x
- uses: actions/checkout@v4
with:
fetch-depth: 0
submodules: recursive
- uses: actions/download-artifact@v4
with:
name: macos ${{ matrix.coin }}
path: release/${{ matrix.coin }}
- name: Run integration tests
run: COIN="${{ matrix.coin }}" deno test -A tests/integration.test.ts
env:
SECRET_WALLET_PASSWORD: ${{ secrets.SECRET_WALLET_PASSWORD }}
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,
]
steps:
- uses: actions/github-script@v7
continue-on-error: true
id: get_issue_number
with:
script: |
if (context.issue.number) {
// Return issue number if present
return context.issue.number;
} else {
// Otherwise return issue number from commit
return (
await github.rest.repos.listPullRequestsAssociatedWithCommit({
commit_sha: context.sha,
owner: context.repo.owner,
repo: context.repo.repo,
})
).data[0].number;
}
result-encoding: string
- name: Find Comment
continue-on-error: true
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{steps.get_issue_number.outputs.result}}
comment-author: 'github-actions[bot]'
body-includes: download artifacts
- name: Update comment
continue-on-error: true
if: steps.fc.outcome == 'success'
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{steps.get_issue_number.outputs.result}}
body: |
[download artifacts #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}})
edit-mode: replace
- name: Create comment
continue-on-error: true
if: steps.fc.outcome == 'failure'
uses: peter-evans/create-or-update-comment@v4
with:
issue-number: ${{steps.get_issue_number.outputs.result}}
body: |
[download artifacts #${{github.run_id}}](https://nightly.link/MrCyjaneK/monero_c/actions/runs/${{github.run_id}}) (this comment will update whenever you push)
+8 -11
View File
@@ -3,16 +3,13 @@
url = https://github.com/monero-project/monero
branch = release-v0.18
shallow = true
[submodule "wownero"]
path = wownero
url = https://codeberg.org/wownero/wownero
[submodule "salvium"]
path = salvium
url = http://54.38.205.168:3000/tiamak/salvium.git
branch = salvium_one
shallow = true
[submodule "zano"]
path = zano
url = https://github.com/hyle-team/zano
shallow = false
[submodule "wownero_libwallet2_api_c/wownero-seed"]
path = wownero_libwallet2_api_c/wownero-seed
url = https://github.com/MrCyjaneK/wownero-seed
branch = cyjan-namespace2
[submodule "peya"]
path = peya
url = http://54.38.205.168:3000/tiamak/Peya.git
branch = develop
shallow = true
+2 -2
View File
@@ -7,9 +7,9 @@
TL;DR:
```bash
$ rm -rf monero wownero release
$ rm -rf monero salvium peya release
$ git submodule update --init --recursive --force
$ for coin in monero wownero zano; do ./apply_patches.sh $coin; done
$ for coin in monero salvium peya; do ./apply_patches.sh $coin; done
```
Broken? Not working? Need help? https://moneroc.mrcyjanek.net/
+5 -16
View File
@@ -6,14 +6,15 @@ repo="$1"
if [[ "x$repo" == "x" ]];
then
echo "Usage: $0 monero/wownero"
echo "Usage: $0 monero/salvium/peya"
exit 1
fi
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" ]];
if [[ "x$repo" != "xmonero" && "x$repo" != "xsalvium" && "x$repo" != "xpeya" ]];
then
echo "Usage: $0 monero/wownero"
echo "Invalid target given, only monero and wownero are supported targets"
echo "Usage: $0 monero/salvium/peya"
echo "Invalid target given, only monero, salvium, and peya are supported targets"
exit 1
fi
if [[ ! -d "$repo" ]]
@@ -32,18 +33,6 @@ fi
set -e
cd $repo
git am -3 --whitespace=fix --reject ../patches/$repo/*.patch
if [[ "$repo" == "wownero" ]];
then
pushd external/randomwow
git remote set-url origin https://github.com/mrcyjanek/randomwow.git
popd
fi
if [[ "$repo" == "zano" ]];
then
pushd contrib/tor-connect
git remote set-url origin https://github.com/mrcyjanek/tor-connect.git
popd
fi
git submodule init
git submodule update --init --recursive --force
git am -3 <<EOF
+6 -10
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/salvium/peya $(gcc -dumpmachine) -j$proccount"
exit 1
fi
if [[ "x$repo" != "xwownero" && "x$repo" != "xmonero" && "x$repo" != "xzano" ]];
if [[ "x$repo" != "xmonero" && "x$repo" != "xsalvium" && "x$repo" != "xpeya" ]];
then
echo "Usage: $0 monero/wownero/zano $(gcc -dumpmachine) -j$proccount"
echo "Usage: $0 monero/salvium/peya $(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/salvium/peya $(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/salvium/peya $(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
@@ -68,10 +68,6 @@ buildType=Debug
pushd ${repo}_libwallet2_api_c
rm -rf build/${HOST_ABI} || true
mkdir -p build/${HOST_ABI} -p
if [[ "$repo" == "zano" ]];
then
EXTRA_CMAKE_FLAGS="-DCAKEWALLET=ON"
fi
pushd build/${HOST_ABI}
cmake -DCMAKE_TOOLCHAIN_FILE=$PWD/../../../contrib/depends/${HOST_ABI}/share/toolchain.cmake $EXTRA_CMAKE_FLAGS -DUSE_DEVICE_TREZOR=OFF -DMONERO_FLAVOR=$repo -DCMAKE_BUILD_TYPE=Debug -DHOST_ABI=${HOST_ABI} ../..
make $NPROC
+1 -1
View File
@@ -17,7 +17,7 @@ $(package)_config_opts_android=threadapi=pthread runtime-link=static target-os=a
$(package)_config_opts_darwin=--toolset=darwin runtime-link=static
$(package)_config_opts_ios=--toolset=darwin-$($(package)_ios_COMPILER_VERSION)~iphone runtime-link=static
$(package)_config_opts_iossimulator=--toolset=darwin-$($(package)_ios_COMPILER_VERSION)~iphone runtime-link=static
$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static
$(package)_config_opts_mingw32=binary-format=pe target-os=windows threadapi=win32 runtime-link=static define=BOOST_LOG_WITHOUT_EVENT_LOG
$(package)_config_opts_x86_64_mingw32=address-model=64
$(package)_config_opts_i686_mingw32=address-model=32
$(package)_config_opts_i686_linux=address-model=32 architecture=x86
+1 -2
View File
@@ -197,7 +197,6 @@ endif()
link_directories(@prefix@/lib)
include_directories(@prefix@/include)
include_directories(@prefix@/include/wownero_seed)
add_definitions(-DPOLYSEED_STATIC=ON)
add_definitions(-DMOBILE_WALLET_BUILD)
@@ -207,4 +206,4 @@ if (ANDROID OR IOS)
endif()
#Create a new global cmake flag that indicates building with depends
set (DEPENDS true)
set (DEPENDS true)
+2 -2
View File
@@ -35,7 +35,7 @@ yourself](https://github.com/MrCyjaneK/unnamed_monero_wallet/blob/master-rewrite
```bash
$ ./build_moneroc.sh
--prebuild # allow downloads of prebuilds
--coin # monero/wownero
--coin # monero/salvium/peya
--tag v0.18.3.3-RC45 # which tag to build / download
--triplet x86_64-linux-android # which triplet to build / download
--location android/.../jniLibs/x86_64 # where to but the libraries
@@ -45,4 +45,4 @@ $ ./build_moneroc.sh
There is a simple script in cake_wallet written in `dart` that runs on all platform (including windows) which downloads
all required libraries for selected platforms in one go.
[You can take look at it here](https://github.com/cake-tech/cake_wallet/blob/main/tool/download_moneroc_prebuilds.dart)
[You can take look at it here](https://github.com/cake-tech/cake_wallet/blob/main/tool/download_moneroc_prebuilds.dart)
+5 -3
View File
@@ -25,7 +25,8 @@ execute_process(WORKING_DIRECTORY monero_c COMMAND git checkout ${MONERO_C_COMMI
execute_process(WORKING_DIRECTORY monero_c COMMAND git submodule update --recursive --force --init)
execute_process(COMMAND rm monero_c/monero/.patch-applied)
execute_process(COMMAND rm monero_c/wownero/.patch-applied)
execute_process(COMMAND rm -f monero_c/salvium/.patch-applied)
execute_process(COMMAND rm -f monero_c/peya/.patch-applied)
# apply patches
@@ -34,7 +35,8 @@ if (MONERO_C_MONERO)
endif()
if (MONERO_C_WOWNERO)
execute_process(WORKING_DIRECTORY monero_c COMMAND ./apply_patches.sh wownero)
execute_process(WORKING_DIRECTORY monero_c COMMAND ./apply_patches.sh salvium)
execute_process(WORKING_DIRECTORY monero_c COMMAND ./apply_patches.sh peya)
endif()
# actually.. build the software
@@ -61,4 +63,4 @@ endif()
add_custom_target(
.host-apple-darwin_monero_libwallet2_api_c.dylib ALL
DEPENDS host-apple-darwin_monero_libwallet2_api_c.dylib
)
)
+1 -2
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 salvium peya;
do
submodule_hash=$(git ls-tree HEAD ${coin} | xargs | awk '{ print $3 }')
COIN=$(echo "$coin" | tr a-z A-Z)
@@ -36,4 +36,3 @@ export const ${coin}Checksum = {
}
EOF
done
+17
View File
@@ -0,0 +1,17 @@
name: PeyaC
description: monero_c peya bindings
output: 'lib/src/generated_bindings_peya.g.dart'
headers:
entry-points:
- '../../peya_libwallet2_api_c/src/main/cpp/wallet2_api_c.h'
exclude-all-by-default: true
functions:
include:
- "PEYA_.+"
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'
+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'
-11
View File
@@ -1,11 +0,0 @@
name: WowneroC
description: monero_c wownero bindings
output: 'lib/src/generated_bindings_wownero.g.dart'
headers:
entry-points:
- '../../wownero_libwallet2_api_c/src/main/cpp/wallet2_api_c.h'
exclude-all-by-default: true
functions:
include:
- "WOWNERO_.+"
-11
View File
@@ -1,11 +0,0 @@
name: ZanoC
description: monero_c bindings
output: 'lib/src/generated_bindings_zano.g.dart'
headers:
entry-points:
- '../../zano_libwallet2_api_c/src/main/cpp/wallet2_api_c.h'
exclude-all-by-default: true
functions:
include:
- "ZANO_.+"
File diff suppressed because it is too large Load Diff
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_h_sha256 = "91218f60e937753a606b1db899ee2ed66a1b02144eb2d79b950ce59804397f84";
const String wallet2_api_c_cpp_sha256 = "282128494f3419c128dff7ed67daadd9c2ad0600d10557e829df03d9bc1ad891-9d2f5b392bc46d56449be92295071fbc2cb3d230";
const String wallet2_api_c_exp_sha256 = "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d";
@@ -0,0 +1,4 @@
// ignore_for_file: constant_identifier_names
const String wallet2_api_c_h_sha256 = "5ccccf76d6ce6a38985030ed89ff49c8d688b7920c38b85e6072bad415e5c28f";
const String wallet2_api_c_cpp_sha256 = "cfbc7bcfb8f8066660a2b19225249d6cc44958272c7816676a32c8ec37fedbda-fd1126fa7b476ab887502f63dd3ee565da4145a0";
const String wallet2_api_c_exp_sha256 = "31b4f92a01ff4812c46e5978c0195f725fe93c87bcd8036391a12fe9d5774621";
@@ -0,0 +1,4 @@
// ignore_for_file: constant_identifier_names
const String wallet2_api_c_h_sha256 = "e058d5ca0dc56bc7c40b55f6428a86bd14dd5b4308c03854ef6a1099aa09d107";
const String wallet2_api_c_cpp_sha256 = "c40f623ef0801ceccba760d49176d84122c683e4f832e304372b9c931a02ed25-42ec3826a079af4411ed2632b9e469d428e884ae";
const String wallet2_api_c_exp_sha256 = "8743a9af4dd98eb5288829226d8815b8f91ad1bd48db10488e65f4b1983549d8";
@@ -1,4 +0,0 @@
// ignore_for_file: constant_identifier_names
const String wallet2_api_c_h_sha256 = "f99009d1ca1d1c783cc9aa0fb63f680d48753b88124fb5de2079c57b7e34c827";
const String wallet2_api_c_cpp_sha256 = "70b39a0bef660cb9ba0397117eb1590e18461ace89ab18141690658a2a537d5d-3e302be710f4e6b4f58642989c8e47711362fa56";
const String wallet2_api_c_exp_sha256 = "5f53ea8bbe66a5e5aa6cbc4ca00695900e08589cfd32062e88965a24252d05ba";
@@ -1,4 +0,0 @@
// ignore_for_file: constant_identifier_names
const String wallet2_api_c_h_sha256 = "8acaa95513b85a984c08e05cc3f2ac7530bb8f32946eeeb45357bd846aef33dd";
const String wallet2_api_c_cpp_sha256 = "4efacd3812d53dd268b6869cc0a9560e7320574d96e09136cf067f796edfeba6-fbeb658ae04bed149c0f52af5e8f1e815249f4d4";
const String wallet2_api_c_exp_sha256 = "66f3ff655bbfd11ad28c318ab707090b5a93276f436b06f7b1c0f329dba3c9c2";
@@ -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,40 @@ 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.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
File diff suppressed because it is too large Load Diff
@@ -1,527 +0,0 @@
// AUTO GENERATED FILE, DO NOT EDIT.
//
// Generated by `package:ffigen`.
// ignore_for_file: type=lint
import 'dart:ffi' as ffi;
/// monero_c bindings
class ZanoC {
/// Holds the symbol lookup function.
final ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
_lookup;
/// The symbols are looked up in [dynamicLibrary].
ZanoC(ffi.DynamicLibrary dynamicLibrary) : _lookup = dynamicLibrary.lookup;
/// The symbols are looked up with [lookup].
ZanoC.fromLookup(
ffi.Pointer<T> Function<T extends ffi.NativeType>(String symbolName)
lookup)
: _lookup = lookup;
ffi.Pointer<ffi.Char> ZANO_PlainWallet_init(
ffi.Pointer<ffi.Char> address,
ffi.Pointer<ffi.Char> working_dir,
int log_level,
) {
return _ZANO_PlainWallet_init(
address,
working_dir,
log_level,
);
}
late final _ZANO_PlainWallet_initPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>, ffi.Int)>>('ZANO_PlainWallet_init');
late final _ZANO_PlainWallet_init = _ZANO_PlainWallet_initPtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_init2(
ffi.Pointer<ffi.Char> ip,
ffi.Pointer<ffi.Char> port,
ffi.Pointer<ffi.Char> working_dir,
int log_level,
) {
return _ZANO_PlainWallet_init2(
ip,
port,
working_dir,
log_level,
);
}
late final _ZANO_PlainWallet_init2Ptr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>,
ffi.Int)>>('ZANO_PlainWallet_init2');
late final _ZANO_PlainWallet_init2 = _ZANO_PlainWallet_init2Ptr.asFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>, int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_reset() {
return _ZANO_PlainWallet_reset();
}
late final _ZANO_PlainWallet_resetPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_reset');
late final _ZANO_PlainWallet_reset =
_ZANO_PlainWallet_resetPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_setLogLevel(
int log_level,
) {
return _ZANO_PlainWallet_setLogLevel(
log_level,
);
}
late final _ZANO_PlainWallet_setLogLevelPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int)>>(
'ZANO_PlainWallet_setLogLevel');
late final _ZANO_PlainWallet_setLogLevel = _ZANO_PlainWallet_setLogLevelPtr
.asFunction<ffi.Pointer<ffi.Char> Function(int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getVersion() {
return _ZANO_PlainWallet_getVersion();
}
late final _ZANO_PlainWallet_getVersionPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_getVersion');
late final _ZANO_PlainWallet_getVersion = _ZANO_PlainWallet_getVersionPtr
.asFunction<ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getWalletFiles() {
return _ZANO_PlainWallet_getWalletFiles();
}
late final _ZANO_PlainWallet_getWalletFilesPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_getWalletFiles');
late final _ZANO_PlainWallet_getWalletFiles =
_ZANO_PlainWallet_getWalletFilesPtr.asFunction<
ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getExportPrivateInfo(
ffi.Pointer<ffi.Char> target_dir,
) {
return _ZANO_PlainWallet_getExportPrivateInfo(
target_dir,
);
}
late final _ZANO_PlainWallet_getExportPrivateInfoPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_getExportPrivateInfo');
late final _ZANO_PlainWallet_getExportPrivateInfo =
_ZANO_PlainWallet_getExportPrivateInfoPtr.asFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_deleteWallet(
ffi.Pointer<ffi.Char> file_name,
) {
return _ZANO_PlainWallet_deleteWallet(
file_name,
);
}
late final _ZANO_PlainWallet_deleteWalletPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_deleteWallet');
late final _ZANO_PlainWallet_deleteWallet = _ZANO_PlainWallet_deleteWalletPtr
.asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getAddressInfo(
ffi.Pointer<ffi.Char> addr,
) {
return _ZANO_PlainWallet_getAddressInfo(
addr,
);
}
late final _ZANO_PlainWallet_getAddressInfoPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_getAddressInfo');
late final _ZANO_PlainWallet_getAddressInfo =
_ZANO_PlainWallet_getAddressInfoPtr.asFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getAppconfig(
ffi.Pointer<ffi.Char> encryption_key,
) {
return _ZANO_PlainWallet_getAppconfig(
encryption_key,
);
}
late final _ZANO_PlainWallet_getAppconfigPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_getAppconfig');
late final _ZANO_PlainWallet_getAppconfig = _ZANO_PlainWallet_getAppconfigPtr
.asFunction<ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_setAppconfig(
ffi.Pointer<ffi.Char> conf_str,
ffi.Pointer<ffi.Char> encryption_key,
) {
return _ZANO_PlainWallet_setAppconfig(
conf_str,
encryption_key,
);
}
late final _ZANO_PlainWallet_setAppconfigPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_setAppconfig');
late final _ZANO_PlainWallet_setAppconfig =
_ZANO_PlainWallet_setAppconfigPtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_generateRandomKey(
int lenght,
) {
return _ZANO_PlainWallet_generateRandomKey(
lenght,
);
}
late final _ZANO_PlainWallet_generateRandomKeyPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Uint64)>>(
'ZANO_PlainWallet_generateRandomKey');
late final _ZANO_PlainWallet_generateRandomKey =
_ZANO_PlainWallet_generateRandomKeyPtr.asFunction<
ffi.Pointer<ffi.Char> Function(int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getLogsBuffer() {
return _ZANO_PlainWallet_getLogsBuffer();
}
late final _ZANO_PlainWallet_getLogsBufferPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_getLogsBuffer');
late final _ZANO_PlainWallet_getLogsBuffer =
_ZANO_PlainWallet_getLogsBufferPtr.asFunction<
ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_truncateLog() {
return _ZANO_PlainWallet_truncateLog();
}
late final _ZANO_PlainWallet_truncateLogPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_truncateLog');
late final _ZANO_PlainWallet_truncateLog = _ZANO_PlainWallet_truncateLogPtr
.asFunction<ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getConnectivityStatus() {
return _ZANO_PlainWallet_getConnectivityStatus();
}
late final _ZANO_PlainWallet_getConnectivityStatusPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_getConnectivityStatus');
late final _ZANO_PlainWallet_getConnectivityStatus =
_ZANO_PlainWallet_getConnectivityStatusPtr.asFunction<
ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_open(
ffi.Pointer<ffi.Char> path,
ffi.Pointer<ffi.Char> password,
) {
return _ZANO_PlainWallet_open(
path,
password,
);
}
late final _ZANO_PlainWallet_openPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_open');
late final _ZANO_PlainWallet_open = _ZANO_PlainWallet_openPtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_restore(
ffi.Pointer<ffi.Char> seed,
ffi.Pointer<ffi.Char> path,
ffi.Pointer<ffi.Char> password,
ffi.Pointer<ffi.Char> seed_password,
) {
return _ZANO_PlainWallet_restore(
seed,
path,
password,
seed_password,
);
}
late final _ZANO_PlainWallet_restorePtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_restore');
late final _ZANO_PlainWallet_restore =
_ZANO_PlainWallet_restorePtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_generate(
ffi.Pointer<ffi.Char> path,
ffi.Pointer<ffi.Char> password,
) {
return _ZANO_PlainWallet_generate(
path,
password,
);
}
late final _ZANO_PlainWallet_generatePtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_generate');
late final _ZANO_PlainWallet_generate =
_ZANO_PlainWallet_generatePtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>, ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getOpenWallets() {
return _ZANO_PlainWallet_getOpenWallets();
}
late final _ZANO_PlainWallet_getOpenWalletsPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_PlainWallet_getOpenWallets');
late final _ZANO_PlainWallet_getOpenWallets =
_ZANO_PlainWallet_getOpenWalletsPtr.asFunction<
ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getWalletStatus(
int h,
) {
return _ZANO_PlainWallet_getWalletStatus(
h,
);
}
late final _ZANO_PlainWallet_getWalletStatusPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int64)>>(
'ZANO_PlainWallet_getWalletStatus');
late final _ZANO_PlainWallet_getWalletStatus =
_ZANO_PlainWallet_getWalletStatusPtr.asFunction<
ffi.Pointer<ffi.Char> Function(int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_closeWallet(
int h,
) {
return _ZANO_PlainWallet_closeWallet(
h,
);
}
late final _ZANO_PlainWallet_closeWalletPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int64)>>(
'ZANO_PlainWallet_closeWallet');
late final _ZANO_PlainWallet_closeWallet = _ZANO_PlainWallet_closeWalletPtr
.asFunction<ffi.Pointer<ffi.Char> Function(int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_invoke(
int h,
ffi.Pointer<ffi.Char> params,
) {
return _ZANO_PlainWallet_invoke(
h,
params,
);
}
late final _ZANO_PlainWallet_invokePtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Int64, ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_invoke');
late final _ZANO_PlainWallet_invoke = _ZANO_PlainWallet_invokePtr.asFunction<
ffi.Pointer<ffi.Char> Function(int, ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_asyncCall(
ffi.Pointer<ffi.Char> method_name,
int instance_id,
ffi.Pointer<ffi.Char> params,
) {
return _ZANO_PlainWallet_asyncCall(
method_name,
instance_id,
params,
);
}
late final _ZANO_PlainWallet_asyncCallPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>, ffi.Uint64,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_asyncCall');
late final _ZANO_PlainWallet_asyncCall =
_ZANO_PlainWallet_asyncCallPtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>, int, ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_tryPullResult(
int instance_id,
) {
return _ZANO_PlainWallet_tryPullResult(
instance_id,
);
}
late final _ZANO_PlainWallet_tryPullResultPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Uint64)>>(
'ZANO_PlainWallet_tryPullResult');
late final _ZANO_PlainWallet_tryPullResult =
_ZANO_PlainWallet_tryPullResultPtr.asFunction<
ffi.Pointer<ffi.Char> Function(int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_syncCall(
ffi.Pointer<ffi.Char> method_name,
int instance_id,
ffi.Pointer<ffi.Char> params,
) {
return _ZANO_PlainWallet_syncCall(
method_name,
instance_id,
params,
);
}
late final _ZANO_PlainWallet_syncCallPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Pointer<ffi.Char>, ffi.Uint64,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_syncCall');
late final _ZANO_PlainWallet_syncCall =
_ZANO_PlainWallet_syncCallPtr.asFunction<
ffi.Pointer<ffi.Char> Function(
ffi.Pointer<ffi.Char>, int, ffi.Pointer<ffi.Char>)>();
bool ZANO_PlainWallet_isWalletExist(
ffi.Pointer<ffi.Char> path,
) {
return _ZANO_PlainWallet_isWalletExist(
path,
);
}
late final _ZANO_PlainWallet_isWalletExistPtr =
_lookup<ffi.NativeFunction<ffi.Bool Function(ffi.Pointer<ffi.Char>)>>(
'ZANO_PlainWallet_isWalletExist');
late final _ZANO_PlainWallet_isWalletExist =
_ZANO_PlainWallet_isWalletExistPtr.asFunction<
bool Function(ffi.Pointer<ffi.Char>)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_getWalletInfo(
int h,
) {
return _ZANO_PlainWallet_getWalletInfo(
h,
);
}
late final _ZANO_PlainWallet_getWalletInfoPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function(ffi.Int64)>>(
'ZANO_PlainWallet_getWalletInfo');
late final _ZANO_PlainWallet_getWalletInfo =
_ZANO_PlainWallet_getWalletInfoPtr.asFunction<
ffi.Pointer<ffi.Char> Function(int)>();
ffi.Pointer<ffi.Char> ZANO_PlainWallet_resetWalletPassword(
int h,
ffi.Pointer<ffi.Char> password,
) {
return _ZANO_PlainWallet_resetWalletPassword(
h,
password,
);
}
late final _ZANO_PlainWallet_resetWalletPasswordPtr = _lookup<
ffi.NativeFunction<
ffi.Pointer<ffi.Char> Function(ffi.Int64,
ffi.Pointer<ffi.Char>)>>('ZANO_PlainWallet_resetWalletPassword');
late final _ZANO_PlainWallet_resetWalletPassword =
_ZANO_PlainWallet_resetWalletPasswordPtr.asFunction<
ffi.Pointer<ffi.Char> Function(int, ffi.Pointer<ffi.Char>)>();
int ZANO_PlainWallet_getCurrentTxFee(
int priority,
) {
return _ZANO_PlainWallet_getCurrentTxFee(
priority,
);
}
late final _ZANO_PlainWallet_getCurrentTxFeePtr =
_lookup<ffi.NativeFunction<ffi.Uint64 Function(ffi.Uint64)>>(
'ZANO_PlainWallet_getCurrentTxFee');
late final _ZANO_PlainWallet_getCurrentTxFee =
_ZANO_PlainWallet_getCurrentTxFeePtr.asFunction<int Function(int)>();
void ZANO_free(
ffi.Pointer<ffi.Void> ptr,
) {
return _ZANO_free(
ptr,
);
}
late final _ZANO_freePtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Void>)>>(
'ZANO_free');
late final _ZANO_free =
_ZANO_freePtr.asFunction<void Function(ffi.Pointer<ffi.Void>)>();
ffi.Pointer<ffi.Char> ZANO_checksum_wallet2_api_c_h() {
return _ZANO_checksum_wallet2_api_c_h();
}
late final _ZANO_checksum_wallet2_api_c_hPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_checksum_wallet2_api_c_h');
late final _ZANO_checksum_wallet2_api_c_h = _ZANO_checksum_wallet2_api_c_hPtr
.asFunction<ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_checksum_wallet2_api_c_cpp() {
return _ZANO_checksum_wallet2_api_c_cpp();
}
late final _ZANO_checksum_wallet2_api_c_cppPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_checksum_wallet2_api_c_cpp');
late final _ZANO_checksum_wallet2_api_c_cpp =
_ZANO_checksum_wallet2_api_c_cppPtr.asFunction<
ffi.Pointer<ffi.Char> Function()>();
ffi.Pointer<ffi.Char> ZANO_checksum_wallet2_api_c_exp() {
return _ZANO_checksum_wallet2_api_c_exp();
}
late final _ZANO_checksum_wallet2_api_c_expPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'ZANO_checksum_wallet2_api_c_exp');
late final _ZANO_checksum_wallet2_api_c_exp =
_ZANO_checksum_wallet2_api_c_expPtr.asFunction<
ffi.Pointer<ffi.Char> Function()>();
}
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
-688
View File
@@ -1,688 +0,0 @@
// ignore_for_file: non_constant_identifier_names, camel_case_types
import 'dart:ffi';
import 'dart:io';
import 'package:ffi/ffi.dart';
import 'package:monero/src/generated_bindings_zano.g.dart';
export 'src/checksum_monero.dart';
typedef PendingTransaction = Pointer<Void>;
ZanoC? lib;
String libPath = (() {
if (Platform.isWindows) return 'zano_libwallet2_api_c.dll';
if (Platform.isMacOS) return 'zano_libwallet2_api_c.dylib';
if (Platform.isIOS) return 'ZanoWallet.framework/ZanoWallet';
if (Platform.isAndroid) return 'libzano_libwallet2_api_c.so';
return 'zano_libwallet2_api_c.so';
})();
Map<String, List<int>> debugCallLength = {};
final defaultSeparatorStr = ";";
final defaultSeparator = defaultSeparatorStr.toNativeUtf8().cast<Char>();
/* we don't call .free here, this comment serves one purpose - so the numbers match :) */
final Stopwatch sw = Stopwatch()..start();
bool printStarts = false;
void Function(String call)? debugStart = (call) {
try {
if (printStarts) print("MONERO: $call");
debugCallLength[call] ??= <int>[];
debugCallLength[call]!.add(sw.elapsedMicroseconds);
} catch (e) {}
};
void debugChores() {
for (var key in debugCallLength.keys) {
if (debugCallLength[key]!.length > 1000000) {
final elm =
debugCallLength[key]!.reduce((value, element) => value + element);
debugCallLength[key]!.clear();
debugCallLength["${key}_1M"] ??= <int>[];
debugCallLength["${key}_1M"]!.add(elm);
}
}
}
int debugCount = 0;
void Function(String call)? debugEnd = (call) {
try {
final id = debugCallLength[call]!.length - 1;
if (++debugCount > 1000000) {
debugCount = 0;
debugChores();
}
debugCallLength[call]![id] =
sw.elapsedMicroseconds - debugCallLength[call]![id];
} catch (e) {}
};
void Function(String call, dynamic error)? errorHandler = (call, error) {
print("$call: $error");
};
// extern ADDAPI const char* ZANO_PlainWallet_init(const char* address, const char* working_dir, int log_level);
String PlainWallet_init(String address, String working_dir, int log_level) {
debugStart?.call('ZANO_PlainWallet_init');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final address_ = address.toNativeUtf8();
final working_dir_ = working_dir.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_init(address_.cast(), working_dir_.cast(), log_level);
calloc.free(address_);
calloc.free(working_dir_);
debugEnd?.call('ZANO_PlainWallet_init');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_init');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_init', e);
debugEnd?.call('ZANO_PlainWallet_init');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_init2(const char* ip, const char* port, const char* working_dir, int log_level);
String PlainWallet_init2(String ip, String port, String working_dir, int log_level) {
debugStart?.call('ZANO_PlainWallet_init2');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final ip_ = ip.toNativeUtf8();
final port_ = port.toNativeUtf8();
final working_dir_ = working_dir.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_init2(ip_.cast(), port_.cast(), working_dir_.cast(), log_level);
calloc.free(ip_);
calloc.free(port_);
calloc.free(working_dir_);
debugEnd?.call('ZANO_PlainWallet_init2');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_init2');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_init2', e);
debugEnd?.call('ZANO_PlainWallet_init2');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_reset();
String PlainWallet_reset() {
debugStart?.call('ZANO_PlainWallet_reset');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_reset();
debugEnd?.call('ZANO_PlainWallet_reset');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_reset');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_reset', e);
debugEnd?.call('ZANO_PlainWallet_reset');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_setLogLevel(int log_level);
String PlainWallet_setLogLevel(int log_level) {
debugStart?.call('ZANO_PlainWallet_setLogLevel');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_setLogLevel(log_level);
debugEnd?.call('ZANO_PlainWallet_setLogLevel');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_setLogLevel');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_setLogLevel', e);
debugEnd?.call('ZANO_PlainWallet_setLogLevel');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getVersion();
String PlainWallet_getVersion() {
debugStart?.call('ZANO_PlainWallet_getVersion');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getVersion();
debugEnd?.call('ZANO_PlainWallet_getVersion');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getVersion');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getVersion', e);
debugEnd?.call('ZANO_PlainWallet_getVersion');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getWalletFiles();
String PlainWallet_getWalletFiles() {
debugStart?.call('ZANO_PlainWallet_getWalletFiles');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getWalletFiles();
debugEnd?.call('ZANO_PlainWallet_getWalletFiles');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getWalletFiles');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getWalletFiles', e);
debugEnd?.call('ZANO_PlainWallet_getWalletFiles');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getExportPrivateInfo(const char* target_dir);
String PlainWallet_getExportPrivateInfo(String target_dir) {
debugStart?.call('ZANO_PlainWallet_getExportPrivateInfo');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final target_dir_ = target_dir.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_getExportPrivateInfo(target_dir_.cast());
calloc.free(target_dir_);
debugEnd?.call('ZANO_PlainWallet_getExportPrivateInfo');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getExportPrivateInfo');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getExportPrivateInfo', e);
debugEnd?.call('ZANO_PlainWallet_getExportPrivateInfo');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_deleteWallet(const char* file_name);
String PlainWallet_deleteWallet(String file_name) {
debugStart?.call('ZANO_PlainWallet_deleteWallet');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final file_name_ = file_name.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_deleteWallet(file_name_.cast());
calloc.free(file_name_);
debugEnd?.call('ZANO_PlainWallet_deleteWallet');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_deleteWallet');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_deleteWallet', e);
debugEnd?.call('ZANO_PlainWallet_deleteWallet');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getAddressInfo(const char* addr);
String PlainWallet_getAddressInfo(String addr) {
debugStart?.call('ZANO_PlainWallet_getAddressInfo');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final addr_ = addr.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_getAddressInfo(addr_.cast());
calloc.free(addr_);
debugEnd?.call('ZANO_PlainWallet_getAddressInfo');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getAddressInfo');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getAddressInfo', e);
debugEnd?.call('ZANO_PlainWallet_getAddressInfo');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getAppconfig(const char* encryption_key);
String PlainWallet_getAppconfig(String encryption_key) {
debugStart?.call('ZANO_PlainWallet_getAppconfig');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final encryption_key_ = encryption_key.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_getAppconfig(encryption_key_.cast());
calloc.free(encryption_key_);
debugEnd?.call('ZANO_PlainWallet_getAppconfig');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getAppconfig');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getAppconfig', e);
debugEnd?.call('ZANO_PlainWallet_getAppconfig');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_setAppconfig(const char* conf_str, const char* encryption_key);
String PlainWallet_setAppconfig(String conf_str, String encryption_key) {
debugStart?.call('ZANO_PlainWallet_setAppconfig');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final conf_str_ = conf_str.toNativeUtf8();
final encryption_key_ = encryption_key.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_setAppconfig(conf_str_.cast(), encryption_key_.cast());
calloc.free(conf_str_);
calloc.free(encryption_key_);
debugEnd?.call('ZANO_PlainWallet_setAppconfig');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_setAppconfig');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_setAppconfig', e);
debugEnd?.call('ZANO_PlainWallet_setAppconfig');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_generateRandomKey(uint64_t lenght);
String PlainWallet_generateRandomKey(int length) {
debugStart?.call('ZANO_PlainWallet_generateRandomKey');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_generateRandomKey(length);
debugEnd?.call('ZANO_PlainWallet_generateRandomKey');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_generateRandomKey');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_generateRandomKey', e);
debugEnd?.call('ZANO_PlainWallet_generateRandomKey');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getLogsBuffer();
String PlainWallet_getLogsBuffer() {
debugStart?.call('ZANO_PlainWallet_getLogsBuffer');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getLogsBuffer();
debugEnd?.call('ZANO_PlainWallet_getLogsBuffer');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getLogsBuffer');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getLogsBuffer', e);
debugEnd?.call('ZANO_PlainWallet_getLogsBuffer');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_truncateLog();
String PlainWallet_truncateLog() {
debugStart?.call('ZANO_PlainWallet_truncateLog');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_truncateLog();
debugEnd?.call('ZANO_PlainWallet_truncateLog');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_truncateLog');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_truncateLog', e);
debugEnd?.call('ZANO_PlainWallet_truncateLog');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getConnectivityStatus();
String PlainWallet_getConnectivityStatus() {
debugStart?.call('ZANO_PlainWallet_getConnectivityStatus');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getConnectivityStatus();
debugEnd?.call('ZANO_PlainWallet_getConnectivityStatus');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getConnectivityStatus');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getConnectivityStatus', e);
debugEnd?.call('ZANO_PlainWallet_getConnectivityStatus');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_open(const char* path, const char* password);
String PlainWallet_open(String path, String password) {
debugStart?.call('ZANO_PlainWallet_open');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final path_ = path.toNativeUtf8();
final password_ = password.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_open(path_.cast(), password_.cast());
calloc.free(path_);
calloc.free(password_);
debugEnd?.call('ZANO_PlainWallet_open');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_open');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_open', e);
debugEnd?.call('ZANO_PlainWallet_open');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_restore(const char* seed, const char* path, const char* password, const char* seed_password);
String PlainWallet_restore(String seed, String path, String password, String seed_password) {
debugStart?.call('ZANO_PlainWallet_restore');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final seed_ = seed.toNativeUtf8();
final path_ = path.toNativeUtf8();
final password_ = password.toNativeUtf8();
final seed_password_ = seed_password.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_restore(seed_.cast(), path_.cast(), password_.cast(), seed_password_.cast());
calloc.free(seed_);
calloc.free(path_);
calloc.free(password_);
calloc.free(seed_password_);
debugEnd?.call('ZANO_PlainWallet_restore');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_restore');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_restore', e);
debugEnd?.call('ZANO_PlainWallet_restore');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_generate(const char* path, const char* password);
String PlainWallet_generate(String path, String password) {
debugStart?.call('ZANO_PlainWallet_generate');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final path_ = path.toNativeUtf8();
final password_ = password.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_generate(path_.cast(), password_.cast());
calloc.free(path_);
calloc.free(password_);
debugEnd?.call('ZANO_PlainWallet_generate');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_generate');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_generate', e);
debugEnd?.call('ZANO_PlainWallet_generate');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getOpenWallets();
String PlainWallet_getOpenWallets() {
debugStart?.call('ZANO_PlainWallet_getOpenWallets');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getOpenWallets();
debugEnd?.call('ZANO_PlainWallet_getOpenWallets');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getOpenWallets');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getOpenWallets', e);
debugEnd?.call('ZANO_PlainWallet_getOpenWallets');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_getWalletStatus(int64_t h);
String PlainWallet_getWalletStatus(int h) {
debugStart?.call('ZANO_PlainWallet_getWalletStatus');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getWalletStatus(h);
debugEnd?.call('ZANO_PlainWallet_getWalletStatus');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getWalletStatus');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getWalletStatus', e);
debugEnd?.call('ZANO_PlainWallet_getWalletStatus');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_closeWallet(int64_t h);
String PlainWallet_closeWallet(int h) {
debugStart?.call('ZANO_PlainWallet_closeWallet');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_closeWallet(h);
debugEnd?.call('ZANO_PlainWallet_closeWallet');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_closeWallet');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_closeWallet', e);
debugEnd?.call('ZANO_PlainWallet_closeWallet');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_invoke(int64_t h, const char* params);
String PlainWallet_invoke(int h, String params) {
debugStart?.call('ZANO_PlainWallet_invoke');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final params_ = params.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_invoke(h, params_.cast());
calloc.free(params_);
debugEnd?.call('ZANO_PlainWallet_invoke');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_invoke');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_invoke', e);
debugEnd?.call('ZANO_PlainWallet_invoke');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_asyncCall(const char* method_name, uint64_t instance_id, const char* params);
String PlainWallet_asyncCall(String method_name, int h, String params) {
debugStart?.call('ZANO_PlainWallet_asyncCall');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final params_ = params.toNativeUtf8();
final method_name_ = method_name.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_asyncCall(method_name_.cast(), h, params_.cast());
calloc.free(params_);
calloc.free(method_name_);
debugEnd?.call('ZANO_PlainWallet_asyncCall');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_asyncCall');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_asyncCall', e);
debugEnd?.call('ZANO_PlainWallet_asyncCall');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_tryPullResult(uint64_t instance_id);
String PlainWallet_tryPullResult(int instance_id) {
debugStart?.call('ZANO_PlainWallet_tryPullResult');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_tryPullResult(instance_id);
debugEnd?.call('ZANO_PlainWallet_tryPullResult');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_tryPullResult');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_tryPullResult', e);
debugEnd?.call('ZANO_PlainWallet_tryPullResult');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_syncCall(const char* method_name, uint64_t instance_id, const char* params);
String PlainWallet_syncCall(String method_name, int instance_id, String params) {
debugStart?.call('ZANO_PlainWallet_syncCall');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final method_name_ = method_name.toNativeUtf8();
final params_ = params.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_syncCall(method_name_.cast(), instance_id, params_.cast());
calloc.free(method_name_);
calloc.free(params_);
debugEnd?.call('ZANO_PlainWallet_syncCall');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_syncCall');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_syncCall', e);
debugEnd?.call('ZANO_PlainWallet_syncCall');
return "";
}
}
// extern ADDAPI bool ZANO_PlainWallet_isWalletExist(const char* path);
bool PlainWallet_isWalletExist(String path) {
debugStart?.call('ZANO_PlainWallet_isWalletExist');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final path_ = path.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_isWalletExist(path_.cast());
calloc.free(path_);
debugEnd?.call('ZANO_PlainWallet_isWalletExist');
return txid;
}
// extern ADDAPI const char* ZANO_PlainWallet_getWalletInfo(int64_t h);
String PlainWallet_getWalletInfo(int h) {
debugStart?.call('ZANO_PlainWallet_getWalletInfo');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getWalletInfo(h);
debugEnd?.call('ZANO_PlainWallet_getWalletInfo');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_getWalletInfo');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_getWalletInfo', e);
debugEnd?.call('ZANO_PlainWallet_getWalletInfo');
return "";
}
}
// extern ADDAPI const char* ZANO_PlainWallet_resetWalletPassword(int64_t h, const char* password);
String PlainWallet_resetWalletPassword(int h, String password) {
debugStart?.call('ZANO_PlainWallet_resetWalletPassword');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final password_ = password.toNativeUtf8();
final txid = lib!.ZANO_PlainWallet_resetWalletPassword(h, password_.cast());
calloc.free(password_);
debugEnd?.call('ZANO_PlainWallet_resetWalletPassword');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_PlainWallet_resetWalletPassword');
return str;
} catch (e) {
errorHandler?.call('ZANO_PlainWallet_resetWalletPassword', e);
debugEnd?.call('ZANO_PlainWallet_resetWalletPassword');
return "";
}
}
// extern ADDAPI uint64_t ZANO_PlainWallet_getCurrentTxFee(uint64_t priority);
int PlainWallet_getCurrentTxFee(int priority) {
debugStart?.call('ZANO_PlainWallet_getCurrentTxFee');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_PlainWallet_getCurrentTxFee(priority);
debugEnd?.call('ZANO_PlainWallet_getCurrentTxFee');
return txid;
}
void ZANO_free(Pointer<Void> wlptr) {
debugStart?.call('ZANO_free');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final s = lib!.ZANO_free(wlptr);
debugEnd?.call('ZANO_free');
return s;
}
// extern ADDAPI const char* ZANO_checksum_wallet2_api_c_h();
String checksum_wallet2_api_c_h() {
debugStart?.call('ZANO_checksum_wallet2_api_c_h');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_checksum_wallet2_api_c_h();
debugEnd?.call('ZANO_checksum_wallet2_api_c_h');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_checksum_wallet2_api_c_h');
return str;
} catch (e) {
errorHandler?.call('ZANO_checksum_wallet2_api_c_h', e);
debugEnd?.call('ZANO_checksum_wallet2_api_c_h');
return "";
}
}
// extern ADDAPI const char* ZANO_checksum_wallet2_api_c_cpp();
String checksum_wallet2_api_c_cpp() {
debugStart?.call('ZANO_checksum_wallet2_api_c_cpp');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_checksum_wallet2_api_c_cpp();
debugEnd?.call('ZANO_checksum_wallet2_api_c_cpp');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_checksum_wallet2_api_c_cpp');
return str;
} catch (e) {
errorHandler?.call('ZANO_checksum_wallet2_api_c_cpp', e);
debugEnd?.call('ZANO_checksum_wallet2_api_c_cpp');
return "";
}
}
// extern ADDAPI const char* ZANO_checksum_wallet2_api_c_exp();
String checksum_wallet2_api_c_exp() {
debugStart?.call('ZANO_checksum_wallet2_api_c_exp');
lib ??= ZanoC(DynamicLibrary.open(libPath));
final txid = lib!.ZANO_checksum_wallet2_api_c_exp();
debugEnd?.call('ZANO_checksum_wallet2_api_c_exp');
try {
final strPtr = txid.cast<Utf8>();
final str = strPtr.toDartString();
ZANO_free(strPtr.cast());
debugEnd?.call('ZANO_checksum_wallet2_api_c_exp');
return str;
} catch (e) {
errorHandler?.call('ZANO_checksum_wallet2_api_c_exp', e);
debugEnd?.call('ZANO_checksum_wallet2_api_c_exp');
return "";
}
}
+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
+2 -2
View File
@@ -4,6 +4,6 @@ set -e
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
dart run ffigen --config ffigen_peya.yaml
+2 -2
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_h_sha256: "91218f60e937753a606b1db899ee2ed66a1b02144eb2d79b950ce59804397f84",
wallet2_api_c_cpp_sha256: "282128494f3419c128dff7ed67daadd9c2ad0600d10557e829df03d9bc1ad891-9d2f5b392bc46d56449be92295071fbc2cb3d230",
wallet2_api_c_exp_sha256: "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d",
}
+5
View File
@@ -0,0 +1,5 @@
export const peyaChecksum = {
wallet2_api_c_h_sha256: "5ccccf76d6ce6a38985030ed89ff49c8d688b7920c38b85e6072bad415e5c28f",
wallet2_api_c_cpp_sha256: "cfbc7bcfb8f8066660a2b19225249d6cc44958272c7816676a32c8ec37fedbda-fd1126fa7b476ab887502f63dd3ee565da4145a0",
wallet2_api_c_exp_sha256: "31b4f92a01ff4812c46e5978c0195f725fe93c87bcd8036391a12fe9d5774621",
}
+5
View File
@@ -0,0 +1,5 @@
export const salviumChecksum = {
wallet2_api_c_h_sha256: "e058d5ca0dc56bc7c40b55f6428a86bd14dd5b4308c03854ef6a1099aa09d107",
wallet2_api_c_cpp_sha256: "c40f623ef0801ceccba760d49176d84122c683e4f832e304372b9c931a02ed25-42ec3826a079af4411ed2632b9e469d428e884ae",
wallet2_api_c_exp_sha256: "8743a9af4dd98eb5288829226d8815b8f91ad1bd48db10488e65f4b1983549d8",
}
-5
View File
@@ -1,5 +0,0 @@
export const wowneroChecksum = {
wallet2_api_c_h_sha256: "f99009d1ca1d1c783cc9aa0fb63f680d48753b88124fb5de2079c57b7e34c827",
wallet2_api_c_cpp_sha256: "70b39a0bef660cb9ba0397117eb1590e18461ace89ab18141690658a2a537d5d-3e302be710f4e6b4f58642989c8e47711362fa56",
wallet2_api_c_exp_sha256: "5f53ea8bbe66a5e5aa6cbc4ca00695900e08589cfd32062e88965a24252d05ba",
}
-5
View File
@@ -1,5 +0,0 @@
export const zanoChecksum = {
wallet2_api_c_h_sha256: "8acaa95513b85a984c08e05cc3f2ac7530bb8f32946eeeb45357bd846aef33dd",
wallet2_api_c_cpp_sha256: "4efacd3812d53dd268b6869cc0a9560e7320574d96e09136cf067f796edfeba6-fbeb658ae04bed149c0f52af5e8f1e815249f4d4",
wallet2_api_c_exp_sha256: "66f3ff655bbfd11ad28c318ab707090b5a93276f436b06f7b1c0f329dba3c9c2",
}
+46 -10
View File
@@ -1,8 +1,17 @@
import { type MoneroSymbols, moneroSymbols, type SymbolName, type WowneroSymbols, wowneroSymbols } from "./symbols.ts";
import {
type MoneroSymbols,
moneroSymbols,
type PeyaSymbols,
peyaSymbols,
type SalviumSymbols,
salviumSymbols,
type SymbolName,
} from "./symbols.ts";
export type MoneroDylib = Deno.DynamicLibrary<MoneroSymbols>;
export type WowneroDylib = Deno.DynamicLibrary<WowneroSymbols>;
export type Dylib = MoneroDylib | WowneroDylib;
export type SalviumDylib = Deno.DynamicLibrary<SalviumSymbols>;
export type PeyaDylib = Deno.DynamicLibrary<PeyaSymbols>;
export type Dylib = MoneroDylib | SalviumDylib | PeyaDylib;
export let dylib: Dylib;
@@ -40,8 +49,8 @@ export function loadMoneroDylib(newDylib?: MoneroDylib) {
dylib = Deno.dlopen(libPath, moneroSymbols);
}
export function loadWowneroDylib(newDylib?: WowneroDylib) {
dylibPrefix = "WOWNERO";
export function loadSalviumDylib(newDylib?: SalviumDylib) {
dylibPrefix = "SALVIUM";
if (newDylib) {
dylib = newDylib;
@@ -51,18 +60,45 @@ export function loadWowneroDylib(newDylib?: WowneroDylib) {
let libPath: string;
switch (Deno.build.os) {
case "darwin":
libPath = "./lib/wownero_libwallet2_api_c.dylib";
libPath = "./lib/salvium_libwallet2_api_c.dylib";
break;
case "android":
libPath = "./lib/libwownero_libwallet2_api_c.so";
libPath = "./lib/libsalvium_libwallet2_api_c.so";
break;
case "windows":
libPath = "./lib/wownero_libwallet2_api_c.dll";
libPath = "./lib/salvium_libwallet2_api_c.dll";
break;
default:
libPath = "./lib/wownero_libwallet2_api_c.so";
libPath = "./lib/salvium_libwallet2_api_c.so";
break;
}
dylib = Deno.dlopen(libPath, wowneroSymbols);
dylib = Deno.dlopen(libPath, salviumSymbols);
}
export function loadPeyaDylib(newDylib?: PeyaDylib) {
dylibPrefix = "PEYA";
if (newDylib) {
dylib = newDylib;
return;
}
let libPath: string;
switch (Deno.build.os) {
case "darwin":
libPath = "./lib/peya_libwallet2_api_c.dylib";
break;
case "android":
libPath = "./lib/libpeya_libwallet2_api_c.so";
break;
case "windows":
libPath = "./lib/peya_libwallet2_api_c.dll";
break;
default:
libPath = "./lib/peya_libwallet2_api_c.so";
break;
}
dylib = Deno.dlopen(libPath, peyaSymbols);
}
+10 -5
View File
@@ -2434,11 +2434,16 @@ export const moneroSymbols = {
export type MoneroSymbols = typeof moneroSymbols;
type ReplaceMonero<T extends string> = T extends `MONERO${infer Y}` ? `WOWNERO${Y}` : never;
export type WowneroSymbols = { [Key in keyof MoneroSymbols as ReplaceMonero<Key>]: MoneroSymbols[Key] };
type ReplacePrefix<T extends string, Prefix extends string> = T extends `MONERO${infer Y}` ? `${Prefix}${Y}` : never;
export type SalviumSymbols = { [Key in keyof MoneroSymbols as ReplacePrefix<Key, "SALVIUM">]: MoneroSymbols[Key] };
export type PeyaSymbols = { [Key in keyof MoneroSymbols as ReplacePrefix<Key, "PEYA">]: MoneroSymbols[Key] };
export type SymbolName = keyof MoneroSymbols extends `MONERO_${infer SymbolName}` ? SymbolName : never;
export const wowneroSymbols = Object.fromEntries(
Object.entries(moneroSymbols).map(([key, value]) => [key.replace("MONERO", "WOWNERO"), value]),
) as WowneroSymbols;
export const salviumSymbols = Object.fromEntries(
Object.entries(moneroSymbols).map(([key, value]) => [key.replace("MONERO", "SALVIUM"), value]),
) as SalviumSymbols;
export const peyaSymbols = Object.fromEntries(
Object.entries(moneroSymbols).map(([key, value]) => [key.replace("MONERO", "PEYA"), value]),
) as PeyaSymbols;
+1 -1
Submodule monero updated: 0232839913...9d2f5b392b
-36
View File
@@ -99,30 +99,16 @@ 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)
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)
endif()
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -exported_symbols_list ${EXPORTED_SYMBOLS_FILE}")
@@ -131,27 +117,6 @@ 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})
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)
@@ -167,6 +132,5 @@ endif()
target_link_libraries( wallet2_api_c
${WALLET_TARGETS}
${EXTRA_LIBS_WOWNEROSEED}
${EXTRA_LIBS_ANDROID}
)
@@ -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_h_sha256 = "91218f60e937753a606b1db899ee2ed66a1b02144eb2d79b950ce59804397f84";
const char * MONERO_wallet2_api_c_cpp_sha256 = "282128494f3419c128dff7ed67daadd9c2ad0600d10557e829df03d9bc1ad891-9d2f5b392bc46d56449be92295071fbc2cb3d230";
const char * MONERO_wallet2_api_c_exp_sha256 = "d0f95f1f3bc49f1f59fe4eb0b61826128d7d3bb75405d5a01a252d02db03097d";
#endif
@@ -2102,62 +2102,63 @@ 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()
Monero::Wallet *wallet = reinterpret_cast<Monero::Wallet*>(wallet_ptr);
return wallet->setDeviceSendData(data, len);
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()
}
@@ -832,15 +832,16 @@ 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));
// };
// 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,22 +1,23 @@
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
@@ -131,10 +132,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 +190,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 +232,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 +262,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 +276,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 = data;
+ receivedFromDeviceLength = len;
+
+ waitsForDeviceSend = false;
+ waitsForDeviceReceive = 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 +338,8 @@ index 000000000..a1733616d
+
+#include "device_io.hpp"
+#include "device_io_hid.hpp"
+#include <mutex>
+#include <condition_variable>
+
+namespace hw {
+ namespace io {
@@ -320,9 +351,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 +363,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 +377,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 +452,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 +465,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 +553,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 +589,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 +640,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,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
@@ -1,7 +1,7 @@
From 799d1825696483da743ff2f92a773fcfbef08557 Mon Sep 17 00:00:00 2001
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 04/15] store crash fix
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)
@@ -38,12 +38,12 @@ the current state.
---
src/wallet/api/wallet.cpp | 25 ++++++++++++-------------
src/wallet/api/wallet.h | 1 -
src/wallet/wallet2.cpp | 12 +++++++++++-
src/wallet/wallet2.cpp | 11 ++++++++++-
src/wallet/wallet2.h | 3 +++
4 files changed, 26 insertions(+), 15 deletions(-)
4 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index e868fa039..899ef044a 100644
index 8fda0bab7..67b170e3d 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -55,8 +55,8 @@ using namespace cryptonote;
@@ -147,7 +147,7 @@ index 1f199a72c..ac7ce2f6a 100644
std::atomic<int> m_refreshIntervalMillis;
std::atomic<bool> m_refreshShouldRescan;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 535005ab1..4e66cdeae 100644
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
@@ -173,19 +173,17 @@ index 535005ab1..4e66cdeae 100644
bool wallet2::set_proxy(const std::string &address)
{
return m_http_client->set_proxy(address);
@@ -4107,8 +4116,9 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
@@ -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)
{
+ LOG_ERROR("SYNCING");
uint64_t next_blocks_start_height;
std::vector<cryptonote::block_complete_entry> next_blocks;
std::vector<parsed_block> next_parsed_blocks;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 632298726..022d0696f 100644
index 2f4ad52f1..daad1e940 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1078,6 +1078,8 @@ private:
@@ -206,5 +204,5 @@ index 632298726..022d0696f 100644
i_wallet2_callback* m_callback;
hw::device::device_type m_key_device_type;
--
2.48.0
2.48.1
@@ -1,7 +1,7 @@
From 5a9148c10ea29a42d8aa08d69e2f4559c8611655 Mon Sep 17 00:00:00 2001
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 05/15] uint64_t missing definition fix
Subject: [PATCH 03/14] 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.0
2.48.1
@@ -1,7 +1,7 @@
From ee6aa49179833c930c1ec10ae2e877aeb87eb8c8 Mon Sep 17 00:00:00 2001
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 06/15] use proper error handling in get_seed
Subject: [PATCH 04/14] use proper error handling in get_seed
---
src/wallet/api/wallet.cpp | 17 ++++++++++++-----
@@ -9,10 +9,10 @@ Subject: [PATCH 06/15] use proper error handling in get_seed
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 899ef044a..e16d8f83f 100644
index 67b170e3d..89df5c517 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -826,12 +826,19 @@ bool WalletImpl::close(bool store)
@@ -763,12 +763,19 @@ bool WalletImpl::close(bool store)
std::string WalletImpl::seed(const std::string& seed_offset) const
{
@@ -38,10 +38,10 @@ index 899ef044a..e16d8f83f 100644
std::string WalletImpl::getSeedLanguage() const
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 4e66cdeae..48267d647 100644
index c9c2dbc82..b827b826f 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1449,11 +1449,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
@@ -1428,11 +1428,13 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
bool keys_deterministic = is_deterministic();
if (!keys_deterministic)
{
@@ -55,7 +55,7 @@ index 4e66cdeae..48267d647 100644
std::cout << "seed_language not set" << std::endl;
return false;
}
@@ -1463,8 +1465,9 @@ bool wallet2::get_seed(epee::wipeable_string& electrum_words, const epee::wipeab
@@ -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))
{
@@ -67,5 +67,5 @@ index 4e66cdeae..48267d647 100644
return true;
--
2.48.0
2.48.1
@@ -1,7 +1,7 @@
From 031df7de0d75d93f78be732d5cac702b0ab193f0 Mon Sep 17 00:00:00 2001
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 07/15] UR functions
Subject: [PATCH 05/14] UR functions
This commit adds UR functions for UR tasks,
I believe that the right place to get
@@ -19,10 +19,8 @@ Things broken in the commit
later. However (considering the purpose
of this patch) it is not a dealbreaker.
---
.gitmodules | 5 +-
.gitmodules | 4 +
CMakeLists.txt | 4 +-
contrib/depends/hosts/darwin.mk | 2 +-
contrib/depends/toolchain.cmake.in | 2 +-
external/CMakeLists.txt | 1 +
external/bc-ur | 1 +
src/device/device_ledger.cpp | 5 +-
@@ -36,69 +34,46 @@ Things broken in the commit
src/wallet/api/wallet2_api.h | 22 +-
src/wallet/wallet2.cpp | 141 +++++++----
src/wallet/wallet2.h | 3 +
17 files changed, 521 insertions(+), 60 deletions(-)
15 files changed, 519 insertions(+), 57 deletions(-)
create mode 160000 external/bc-ur
diff --git a/.gitmodules b/.gitmodules
index 991071fbe..b24855d9b 100644
index ffb73fe9a..72af74d55 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -16,4 +16,7 @@
path = external/randomwow
url = https://codeberg.org/wownero/RandomWOW
branch = 1.2.1-wow
-
@@ -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 b4b8c8089..88335ee9d 100644
index db69b1b04..c73b813d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -96,7 +96,8 @@ enable_language(C ASM)
set(CMAKE_C_STANDARD 11)
@@ -100,6 +100,7 @@ enable_language(C ASM)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
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)
@@ -365,6 +366,7 @@ if(NOT MANUAL_SUBMODULES)
@@ -367,6 +368,7 @@ if(NOT MANUAL_SUBMODULES)
endfunction ()
message(STATUS "Checking submodules")
+ #check_submodule(external/bc-ur)
+# check_submodule(external/bc-ur)
check_submodule(external/miniupnp)
check_submodule(external/rapidjson)
#check_submodule(external/trezor-common)
diff --git a/contrib/depends/hosts/darwin.mk b/contrib/depends/hosts/darwin.mk
index 79d449054..83d83036b 100644
--- a/contrib/depends/hosts/darwin.mk
+++ b/contrib/depends/hosts/darwin.mk
@@ -1,4 +1,4 @@
-OSX_MIN_VERSION=10.8
+OSX_MIN_VERSION=10.14
LD64_VERSION=609
ifeq (aarch64, $(host_arch))
CC_target=arm64-apple-$(host_os)
diff --git a/contrib/depends/toolchain.cmake.in b/contrib/depends/toolchain.cmake.in
index f118c754e..f26655d68 100644
--- a/contrib/depends/toolchain.cmake.in
+++ b/contrib/depends/toolchain.cmake.in
@@ -94,7 +94,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
SET(BREW OFF)
SET(PORT OFF)
SET(CMAKE_OSX_SYSROOT "@prefix@/native/SDK/")
- SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.08")
+ SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.14")
SET(CMAKE_CXX_STANDARD 14)
SET(LLVM_ENABLE_PIC OFF)
SET(LLVM_ENABLE_PIE OFF)
check_submodule(external/trezor-common)
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index 29aed0cc6..dfdffe67c 100644
index 538e4d215..074e23f16 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -69,4 +69,5 @@ endif()
@@ -106,36 +81,16 @@ index 29aed0cc6..dfdffe67c 100644
add_subdirectory(easylogging++)
add_subdirectory(qrcodegen)
+add_subdirectory(bc-ur)
add_subdirectory(randomwow EXCLUDE_FROM_ALL)
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 @@
@@ -0,0 +1,1 @@
+Subproject commit d82e7c753e710b8000706dc3383b498438795208
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index 9961d13e7..8403d76e8 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -313,12 +313,13 @@ namespace hw {
/* ======================================================================= */
/* LOCKER */
- /* ======================================================================= */
+ /* ======================================================================= */
//automatic lock one more level on device ensuring the current thread is allowed to use it
+ #pragma message ("Warning AUTO_LOCK_CMD is intentionally left broken. This is yet to be fixed.")
#define AUTO_LOCK_CMD() \
/* lock both mutexes without deadlock*/ \
- boost::lock(device_locker, command_locker); \
+ /* boost::lock(device_locker, command_locker); */ \
/* make sure both already-locked mutexes are unlocked at the end of scope */ \
boost::lock_guard<boost::recursive_mutex> lock1(device_locker, boost::adopt_lock); \
boost::lock_guard<boost::mutex> lock2(command_locker, boost::adopt_lock)
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index fdf3f2f5d..66384fe31 100644
index 6095f99d5..b163212b7 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -50,6 +50,7 @@ monero_add_library(wallet
@@ -144,8 +99,8 @@ index fdf3f2f5d..66384fe31 100644
rpc_base
+ bc-ur
multisig
carrot_impl
common
cryptonote_core
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
@@ -282,10 +237,10 @@ index 30065a7fa..a94b23f75 100644
uint64_t minMixinCount() const override;
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index e16d8f83f..ee000e7ab 100644
index 89df5c517..3fcd6f332 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -47,6 +47,7 @@
@@ -48,6 +48,7 @@
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>
@@ -293,11 +248,11 @@ index e16d8f83f..ee000e7ab 100644
using namespace std;
using namespace cryptonote;
@@ -1066,6 +1067,24 @@ uint64_t WalletImpl::unlockedBalance(uint32_t accountIndex) const
return m_wallet->unlocked_balance(accountIndex, false);
@@ -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
+uint64_t WalletImpl::viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images, const std::string& asset) const
+{
+ clearStatus();
+
@@ -312,13 +267,13 @@ index e16d8f83f..ee000e7ab 100644
+ kis.push_back(ki);
+ }
+
+ return m_wallet->view_only_balance(accountIndex, kis);
+ return m_wallet->view_only_balance(accountIndex, kis, asset);
+}
+
uint64_t WalletImpl::blockChainHeight() const
{
if(m_wallet->light_wallet()) {
@@ -1208,6 +1227,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return m_wallet->get_blockchain_current_height();
@@ -1139,6 +1158,61 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file
return transaction;
}
@@ -380,16 +335,7 @@ index e16d8f83f..ee000e7ab 100644
bool WalletImpl::submitTransaction(const string &fileName) {
clearStatus();
if (checkBackgroundSync("cannot submit tx"))
@@ -1219,7 +1293,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
setStatus(Status_Ok, tr("Failed to load transaction from file"));
return false;
}
-
+
if(!transaction->commit()) {
setStatusError(transaction->m_errorString);
return false;
@@ -1228,6 +1302,61 @@ bool WalletImpl::submitTransaction(const string &fileName) {
@@ -1159,6 +1233,61 @@ bool WalletImpl::submitTransaction(const string &fileName) {
return true;
}
@@ -451,7 +397,7 @@ index e16d8f83f..ee000e7ab 100644
bool WalletImpl::exportKeyImages(const string &filename, bool all)
{
if (m_wallet->watch_only())
@@ -1255,6 +1384,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
@@ -1186,6 +1318,39 @@ bool WalletImpl::exportKeyImages(const string &filename, bool all)
return true;
}
@@ -491,7 +437,7 @@ index e16d8f83f..ee000e7ab 100644
bool WalletImpl::importKeyImages(const string &filename)
{
if (checkBackgroundSync("cannot import key images"))
@@ -1280,6 +1442,62 @@ bool WalletImpl::importKeyImages(const string &filename)
@@ -1211,6 +1373,62 @@ bool WalletImpl::importKeyImages(const string &filename)
return true;
}
@@ -554,7 +500,7 @@ index e16d8f83f..ee000e7ab 100644
bool WalletImpl::exportOutputs(const string &filename, bool all)
{
if (checkBackgroundSync("cannot export outputs"))
@@ -1312,6 +1530,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
@@ -1243,6 +1461,40 @@ bool WalletImpl::exportOutputs(const string &filename, bool all)
return true;
}
@@ -595,7 +541,7 @@ index e16d8f83f..ee000e7ab 100644
bool WalletImpl::importOutputs(const string &filename)
{
if (checkBackgroundSync("cannot import outputs"))
@@ -1346,6 +1598,61 @@ bool WalletImpl::importOutputs(const string &filename)
@@ -1277,6 +1529,61 @@ bool WalletImpl::importOutputs(const string &filename)
return true;
}
@@ -661,16 +607,16 @@ 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
@@ -112,6 +112,7 @@ public:
@@ -113,6 +113,7 @@ public:
bool setProxy(const std::string &address) override;
uint64_t balance(uint32_t accountIndex = 0) const override;
uint64_t unlockedBalance(uint32_t accountIndex = 0) const override;
+ uint64_t viewOnlyBalance(uint32_t accountIndex, const std::vector<std::string> &key_images) const 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;
@@ -164,11 +165,18 @@ public:
std::set<uint32_t> subaddr_indices = {}) 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;
@@ -692,7 +638,7 @@ 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
@@ -91,6 +91,7 @@ struct PendingTransaction
@@ -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;
@@ -700,7 +646,7 @@ index e349df176..764adbfbf 100644
virtual uint64_t amount() const = 0;
virtual uint64_t dust() const = 0;
virtual uint64_t fee() const = 0;
@@ -160,7 +161,8 @@ struct UnsignedTransaction
@@ -195,7 +196,8 @@ struct UnsignedTransaction
* @param signedFileName
* return - true on success
*/
@@ -710,15 +656,15 @@ index e349df176..764adbfbf 100644
};
/**
@@ -626,6 +628,7 @@ struct Wallet
result += unlockedBalance(i);
@@ -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 = 0;
+ 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
@@ -884,13 +887,15 @@ struct Wallet
@@ -965,13 +968,15 @@ struct Wallet
* after object returned
*/
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0;
@@ -737,7 +683,7 @@ index e349df176..764adbfbf 100644
/*!
* \brief disposeTransaction - destroys transaction object
@@ -906,6 +911,8 @@ struct Wallet
@@ -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;
@@ -746,7 +692,7 @@ index e349df176..764adbfbf 100644
/*!
* \brief exportKeyImages - exports key images to file
* \param filename
@@ -913,20 +920,22 @@ struct Wallet
@@ -994,20 +1001,22 @@ struct Wallet
* \return - true on success
*/
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
@@ -771,7 +717,7 @@ index e349df176..764adbfbf 100644
/*!
* \brief importOutputs - imports outputs from file
@@ -934,6 +943,7 @@ struct Wallet
@@ -1015,6 +1024,7 @@ struct Wallet
* \return - true on success
*/
virtual bool importOutputs(const std::string &filename) = 0;
@@ -780,10 +726,10 @@ index e349df176..764adbfbf 100644
/*!
* \brief scanTransactions - scan a list of transaction ids, this operation may reveal the txids to the remote node and affect your privacy
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 48267d647..e14d4d2fc 100644
index b827b826f..765cefb32 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -948,6 +948,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
@@ -945,6 +945,16 @@ uint32_t get_subaddress_clamped_sum(uint32_t idx, uint32_t extra)
return idx + extra;
}
@@ -800,33 +746,37 @@ index 48267d647..e14d4d2fc 100644
static void setup_shim(hw::wallet_shim * shim, tools::wallet2 * wallet)
{
shim->get_tx_pub_key_from_received_outs = std::bind(&tools::wallet2::get_tx_pub_key_from_received_outs, wallet, std::placeholders::_1);
@@ -6998,6 +7008,25 @@ uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *
@@ -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)
+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;
+ for (const auto &td : m_transfers) {
+ 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)
+ if (m_transfers_indices.count(asset_type) > 0) {
+ for (const auto& idx: m_transfers_indices.at(asset_type))
+ {
+ amount += td.m_amount;
+ 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, bool strict) const
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;
@@ -7849,9 +7878,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
@@ -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;
@@ -837,7 +787,7 @@ index 48267d647..e14d4d2fc 100644
std::vector<crypto::public_key> additional_tx_pub_keys;
for (const crypto::secret_key &skey: txs[n].additional_tx_keys)
{
@@ -11241,7 +11268,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
@@ -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;
}
@@ -846,7 +796,7 @@ index 48267d647..e14d4d2fc 100644
{
if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
{
@@ -11291,9 +11318,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
@@ -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");
@@ -864,8 +814,8 @@ index 48267d647..e14d4d2fc 100644
// 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({});
@@ -13920,33 +13953,40 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle
@@ -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);
@@ -928,7 +878,7 @@ index 48267d647..e14d4d2fc 100644
//----------------------------------------------------------------------------------------------------
std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>> wallet2::export_key_images(bool all) const
{
@@ -14001,53 +14041,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
@@ -13828,53 +13868,60 @@ std::pair<uint64_t, std::vector<std::pair<crypto::key_image, crypto::signature>>
return std::make_pair(offset, ski);
}
@@ -1008,18 +958,18 @@ index 48267d647..e14d4d2fc 100644
ski.push_back(std::make_pair(key_image, signature));
}
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 022d0696f..746e2aeff 100644
index daad1e940..a752f15b9 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1157,6 +1157,7 @@ private:
@@ -1112,6 +1112,7 @@ private:
// locked & unlocked balance of given or current subaddress account
uint64_t balance(uint32_t subaddr_index_major, bool strict) const;
uint64_t unlocked_balance(uint32_t subaddr_index_major, 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 = {});
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, bool strict) const;
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict);
@@ -1631,9 +1632,11 @@ private:
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;
@@ -1032,5 +982,5 @@ index 022d0696f..746e2aeff 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.0
2.48.1
@@ -1,43 +1,59 @@
From 221fb7ed81aff1830b4bc2d7f9b73c94eb36924a 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 08/15] 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 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
@@ -69,7 +85,7 @@ index e4f1159b5..14d398f87 100644
${device_headers}
device_ledger.hpp
diff --git a/src/device/device.cpp b/src/device/device.cpp
index e6cd358b6..777584c01 100644
index e6cd358b6..dd0701e0c 100644
--- a/src/device/device.cpp
+++ b/src/device/device.cpp
@@ -29,7 +29,7 @@
@@ -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,14 +392,17 @@ 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);
+ };
+ };
+};
+
+#endif // HAVE_HIDAPI
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index 8403d76e8..0587eb7d3 100644
index bb5b6f497..046201a1e 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -41,7 +41,7 @@ namespace hw {
@@ -360,8 +412,8 @@ index 8403d76e8..0587eb7d3 100644
- #ifdef WITH_DEVICE_LEDGER
+ #if defined(WITH_DEVICE_LEDGER) || defined(HIDAPI_DUMMY)
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "device.ledger"
namespace {
bool apdu_verbose =true;
@@ -299,7 +299,7 @@ namespace hw {
device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 2000) {
@@ -390,9 +442,9 @@ index 03058c4f1..39454ca6d 100644
#include "log.hpp"
#include "device_io_hid.hpp"
+#include "device_io_dummy.hpp"
#include <boost/thread/mutex.hpp>
#include <boost/thread/recursive_mutex.hpp>
#include <mutex>
namespace hw {
@@ -56,7 +57,7 @@ namespace hw {
void register_all(std::map<std::string, std::unique_ptr<device>> &registry);
@@ -402,8 +454,8 @@ index 03058c4f1..39454ca6d 100644
// Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h
#define SW_OK 0x9000
@@ -148,7 +149,11 @@ namespace hw {
mutable boost::mutex command_locker;
@@ -142,7 +143,11 @@ namespace hw {
mutable std::mutex command_locker;
//IO
+#if defined(HIDAPI_DUMMY) && !defined(HAVE_HIDAPI)
@@ -415,10 +467,10 @@ 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 ee000e7ab..556e2a8ce 100644
index 3fcd6f332..844a1c451 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -48,6 +48,9 @@
@@ -49,6 +49,9 @@
#include <boost/locale.hpp>
#include <boost/filesystem.hpp>
#include "bc-ur/src/bc-ur.hpp"
@@ -428,91 +480,87 @@ index ee000e7ab..556e2a8ce 100644
using namespace std;
using namespace cryptonote;
@@ -3178,4 +3181,95 @@ uint64_t WalletImpl::getBytesSent()
@@ -3178,6 +3181,103 @@ 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,27 @@ index ee000e7ab..556e2a8ce 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
+}
+
} // namespace
+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..4e9c21ecb 100644
index edf8bb8ce..6bfb61cb8 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -301,6 +301,24 @@ private:
@@ -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{};
@@ -546,36 +606,33 @@ 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
@@ -1231,6 +1231,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));
/**
//! 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
@@ -600,5 +657,5 @@ index e81b8f83a..277be6ac9 100644
std::vector<std::string> WalletManagerImpl::findWallets(const std::string &path)
--
2.48.0
2.49.0
@@ -1,45 +1,35 @@
From d146c6c1e23e1bf3762449e72a3aab847b3c0412 Mon Sep 17 00:00:00 2001
From c54ab3f0984159bd47c63b78074caaaac082727a Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 09:42:37 +0100
Subject: [PATCH 09/15] polyseed
Subject: [PATCH 07/14] polyseed
Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
---
.gitmodules | 6 +
CMakeLists.txt | 4 +-
contrib/depends/hosts/darwin.mk | 2 +
contrib/depends/hosts/linux.mk | 8 +-
contrib/depends/packages/packages.mk | 2 +-
contrib/depends/packages/polyseed.mk | 28 +++
contrib/depends/packages/sodium.mk | 2 +-
.../polyseed/0001-disable-soname.patch | 48 +++++
.../patches/polyseed/force-static-mingw.patch | 23 +++
contrib/epee/include/wipeable_string.h | 7 +
contrib/epee/src/wipeable_string.cpp | 10 +
external/CMakeLists.txt | 2 +
external/polyseed | 1 +
external/utf8proc | 1 +
src/CMakeLists.txt | 1 +
src/cryptonote_basic/CMakeLists.txt | 1 +
src/cryptonote_basic/account.cpp | 23 ++-
src/cryptonote_basic/account.h | 6 +
src/cryptonote_config.h | 2 +
src/polyseed/CMakeLists.txt | 25 +++
src/polyseed/pbkdf2.c | 85 ++++++++
src/polyseed/pbkdf2.h | 46 +++++
src/polyseed/polyseed.cpp | 182 ++++++++++++++++++
src/polyseed/polyseed.hpp | 167 ++++++++++++++++
src/wallet/api/wallet.cpp | 70 +++++++
src/wallet/api/wallet.h | 10 +
src/wallet/api/wallet2_api.h | 25 +++
src/wallet/api/wallet_manager.cpp | 9 +
src/wallet/api/wallet_manager.h | 10 +
src/wallet/wallet2.cpp | 99 ++++++++--
src/wallet/wallet2.h | 30 ++-
31 files changed, 912 insertions(+), 23 deletions(-)
create mode 100644 contrib/depends/packages/polyseed.mk
create mode 100644 contrib/depends/patches/polyseed/0001-disable-soname.patch
create mode 100644 contrib/depends/patches/polyseed/force-static-mingw.patch
.gitmodules | 6 +
CMakeLists.txt | 4 +-
contrib/epee/include/wipeable_string.h | 7 +
contrib/epee/src/wipeable_string.cpp | 10 ++
external/CMakeLists.txt | 2 +
external/polyseed | 1 +
external/utf8proc | 1 +
src/CMakeLists.txt | 1 +
src/cryptonote_basic/CMakeLists.txt | 1 +
src/cryptonote_basic/account.cpp | 23 +++-
src/cryptonote_basic/account.h | 6 +
src/cryptonote_config.h | 2 +
src/polyseed/CMakeLists.txt | 25 ++++
src/polyseed/pbkdf2.c | 85 ++++++++++++
src/polyseed/pbkdf2.h | 46 +++++++
src/polyseed/polyseed.cpp | 182 +++++++++++++++++++++++++
src/polyseed/polyseed.hpp | 167 +++++++++++++++++++++++
src/wallet/api/wallet.cpp | 70 ++++++++++
src/wallet/api/wallet.h | 10 ++
src/wallet/api/wallet2_api.h | 25 ++++
src/wallet/api/wallet_manager.cpp | 9 ++
src/wallet/api/wallet_manager.h | 10 ++
src/wallet/wallet2.cpp | 100 ++++++++++++--
src/wallet/wallet2.h | 30 +++-
24 files changed, 805 insertions(+), 18 deletions(-)
create mode 160000 external/polyseed
create mode 160000 external/utf8proc
create mode 100644 src/polyseed/CMakeLists.txt
@@ -49,219 +39,44 @@ Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
create mode 100644 src/polyseed/polyseed.hpp
diff --git a/.gitmodules b/.gitmodules
index b24855d9b..589676649 100644
index 72af74d55..b838e84e0 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -20,3 +20,9 @@
path = external/bc-ur
url = https://github.com/MrCyjaneK/bc-ur
branch = misc
@@ -11,6 +11,12 @@
path = external/randomx
url = https://github.com/MrCyjaneK/RandomX
branch = cyjan-fix-ios
+[submodule "external/utf8proc"]
+ path = external/utf8proc
+ url = https://github.com/JuliaStrings/utf8proc.git
+[submodule "external/polyseed"]
+ path = external/polyseed
+ url = https://github.com/tevador/polyseed.git
\ No newline at end of file
[submodule "external/supercop"]
path = external/supercop
url = https://github.com/monero-project/supercop
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 86000f811..96056e324 100644
index 5c0f31cb8..f0630ef9b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -372,6 +372,8 @@ if(NOT MANUAL_SUBMODULES)
#check_submodule(external/trezor-common)
check_submodule(external/randomwow)
check_submodule(external/randomx)
check_submodule(external/supercop)
check_submodule(external/mx25519)
+ check_submodule(external/polyseed)
+ check_submodule(external/utf8proc)
endif()
endif()
@@ -461,7 +463,7 @@ endif()
# elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
# set(BSDI TRUE)
@@ -460,7 +462,7 @@ endif()
set(BSDI TRUE)
endif()
-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include)
+include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/polyseed/include external/utf8proc)
-include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/mx25519/include)
+include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include external/mx25519/include external/polyseed/include external/utf8proc)
if(APPLE)
cmake_policy(SET CMP0042 NEW)
diff --git a/contrib/depends/hosts/darwin.mk b/contrib/depends/hosts/darwin.mk
index 83d83036b..b14ee5c5b 100644
--- a/contrib/depends/hosts/darwin.mk
+++ b/contrib/depends/hosts/darwin.mk
@@ -8,6 +8,8 @@ endif
darwin_CC=clang -target $(CC_target) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(host_prefix)/native/SDK/ -mlinker-version=$(LD64_VERSION) -B$(host_prefix)/native/bin/$(host)-
darwin_CXX=clang++ -target $(CC_target) -mmacosx-version-min=$(OSX_MIN_VERSION) --sysroot $(host_prefix)/native/SDK/ -mlinker-version=$(LD64_VERSION) -stdlib=libc++ -B$(host_prefix)/native/bin/$(host)-
+darwin_RANLIB=$(host_prefix)/native/bin/$(host)-ranlib
+
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS)
darwin_ARFLAGS=cr
diff --git a/contrib/depends/hosts/linux.mk b/contrib/depends/hosts/linux.mk
index 912fdb03c..b79799f30 100644
--- a/contrib/depends/hosts/linux.mk
+++ b/contrib/depends/hosts/linux.mk
@@ -11,15 +11,15 @@ linux_debug_CXXFLAGS=$(linux_debug_CFLAGS)
linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC
ifeq (86,$(findstring 86,$(build_arch)))
-i686_linux_CC=gcc -m32
-i686_linux_CXX=g++ -m32
+i686_linux_CC=i686-linux-gnu-gcc
+i686_linux_CXX=i686-linux-gnu-g++
i686_linux_AR=ar
i686_linux_RANLIB=ranlib
i686_linux_NM=nm
i686_linux_STRIP=strip
-x86_64_linux_CC=gcc -m64
-x86_64_linux_CXX=g++ -m64
+x86_64_linux_CC=x86_64-linux-gnu-gcc
+x86_64_linux_CXX=x86_64-linux-gnu-g++
x86_64_linux_AR=ar
x86_64_linux_RANLIB=ranlib
x86_64_linux_NM=nm
diff --git a/contrib/depends/packages/packages.mk b/contrib/depends/packages/packages.mk
index d2d1eca85..8783d4955 100644
--- a/contrib/depends/packages/packages.mk
+++ b/contrib/depends/packages/packages.mk
@@ -1,4 +1,4 @@
-packages:=boost openssl zeromq libiconv expat unbound
+packages:=boost openssl zeromq libiconv expat unbound polyseed
# ccache is useless in gitian builds
ifneq ($(GITIAN),1)
diff --git a/contrib/depends/packages/polyseed.mk b/contrib/depends/packages/polyseed.mk
new file mode 100644
index 000000000..0071b20f3
--- /dev/null
+++ b/contrib/depends/packages/polyseed.mk
@@ -0,0 +1,28 @@
+package=polyseed
+$(package)_version=2.0.0
+$(package)_download_path=https://github.com/tevador/$(package)/archive/refs/tags/
+$(package)_download_file=v$($(package)_version).tar.gz
+$(package)_file_name=$(package)-$($(package)_version).tar.gz
+$(package)_sha256_hash=f36282fcbcd68d32461b8230c89e1a40661bd46b91109681cec637433004135a
+$(package)_patches=force-static-mingw.patch 0001-disable-soname.patch
+
+define $(package)_preprocess_cmds
+ patch -p1 < $($(package)_patch_dir)/force-static-mingw.patch &&\
+ patch -p1 < $($(package)_patch_dir)/0001-disable-soname.patch
+endef
+
+define $(package)_config_cmds
+ CC="$($(package)_cc)" cmake -DCMAKE_INSTALL_PREFIX="$(host_prefix)" .
+endef
+
+define $(package)_set_vars
+ $(package)_build_opts=CC="$($(package)_cc)"
+endef
+
+define $(package)_build_cmds
+ CC="$($(package)_cc)" $(MAKE)
+endef
+
+define $(package)_stage_cmds
+ $(MAKE) DESTDIR=$($(package)_staging_dir) install
+endef
diff --git a/contrib/depends/packages/sodium.mk b/contrib/depends/packages/sodium.mk
index 87b34599e..68a5b48ba 100644
--- a/contrib/depends/packages/sodium.mk
+++ b/contrib/depends/packages/sodium.mk
@@ -6,7 +6,7 @@ $(package)_sha256_hash=6f504490b342a4f8a4c4a02fc9b866cbef8622d5df4e5452b46be121e
$(package)_patches=disable-glibc-getrandom-getentropy.patch fix-whitespace.patch
define $(package)_set_vars
-$(package)_config_opts=--enable-static --disable-shared
+$(package)_config_opts=--enable-static --disable-shared --with-pic
$(package)_config_opts+=--prefix=$(host_prefix)
endef
diff --git a/contrib/depends/patches/polyseed/0001-disable-soname.patch b/contrib/depends/patches/polyseed/0001-disable-soname.patch
new file mode 100644
index 000000000..bd97dd394
--- /dev/null
+++ b/contrib/depends/patches/polyseed/0001-disable-soname.patch
@@ -0,0 +1,48 @@
+From aabafcfc0572651436d024a635483c49042fad7f Mon Sep 17 00:00:00 2001
+From: Czarek Nakamoto <cyjan@mrcyjanek.net>
+Date: Thu, 28 Mar 2024 00:32:51 +0100
+Subject: [PATCH] disable soname
+
+---
+ CMakeLists.txt | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 8a8e7c2..5301353 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -36,6 +36,7 @@ include_directories(polyseed
+ target_compile_definitions(polyseed PRIVATE POLYSEED_SHARED)
+ set_target_properties(polyseed PROPERTIES VERSION 2.0.0
+ SOVERSION 2
++ NO_SONAME 1
+ C_STANDARD 11
+ C_STANDARD_REQUIRED ON)
+
+@@ -45,16 +46,17 @@ include_directories(polyseed_static
+ include/)
+ target_compile_definitions(polyseed_static PRIVATE POLYSEED_STATIC)
+ set_target_properties(polyseed_static PROPERTIES OUTPUT_NAME polyseed
++ NO_SONAME 1
+ C_STANDARD 11
+ C_STANDARD_REQUIRED ON)
+
+-add_executable(polyseed-tests
+- tests/tests.c)
+-include_directories(polyseed-tests
+- include/)
+-target_compile_definitions(polyseed-tests PRIVATE POLYSEED_STATIC)
+-target_link_libraries(polyseed-tests
+- PRIVATE polyseed_static)
++# add_executable(polyseed-tests
++# tests/tests.c)
++# include_directories(polyseed-tests
++# include/)
++# target_compile_definitions(polyseed-tests PRIVATE POLYSEED_STATIC)
++# target_link_libraries(polyseed-tests
++# PRIVATE polyseed_static)
+
+ include(GNUInstallDirs)
+ install(TARGETS polyseed polyseed_static
+--
+2.39.2
diff --git a/contrib/depends/patches/polyseed/force-static-mingw.patch b/contrib/depends/patches/polyseed/force-static-mingw.patch
new file mode 100644
index 000000000..f05cb2b6a
--- /dev/null
+++ b/contrib/depends/patches/polyseed/force-static-mingw.patch
@@ -0,0 +1,23 @@
+--- a/include/polyseed.h
++++ b/include/polyseed.h
+@@ -93,13 +93,13 @@ Shared/static library definitions
+ - define POLYSEED_STATIC when linking to the static library
+ */
+ #if defined(_WIN32) || defined(__CYGWIN__)
+- #ifdef POLYSEED_SHARED
+- #define POLYSEED_API __declspec(dllexport)
+- #elif !defined(POLYSEED_STATIC)
+- #define POLYSEED_API __declspec(dllimport)
+- #else
+- #define POLYSEED_API
+- #endif
++// #ifdef POLYSEED_SHARED
++// #define POLYSEED_API __declspec(dllexport)
++// #elif !defined(POLYSEED_STATIC)
++// #define POLYSEED_API __declspec(dllimport)
++// #else
++ #define POLYSEED_API
++// #endif
+ #define POLYSEED_PRIVATE
+ #else
+ #ifdef POLYSEED_SHARED
diff --git a/contrib/epee/include/wipeable_string.h b/contrib/epee/include/wipeable_string.h
index 65977cd97..594e15de4 100644
--- a/contrib/epee/include/wipeable_string.h
@@ -307,16 +122,17 @@ index b016f2f48..f2f365b1b 100644
+
}
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index dfdffe67c..fa98f61b5 100644
index 074e23f16..f7e35f98f 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -70,4 +70,6 @@ add_subdirectory(db_drivers)
@@ -70,5 +70,7 @@ endif()
add_subdirectory(db_drivers)
add_subdirectory(easylogging++)
add_subdirectory(qrcodegen)
add_subdirectory(bc-ur)
+add_subdirectory(polyseed EXCLUDE_FROM_ALL)
+add_subdirectory(utf8proc EXCLUDE_FROM_ALL)
add_subdirectory(randomwow EXCLUDE_FROM_ALL)
add_subdirectory(bc-ur)
add_subdirectory(randomx EXCLUDE_FROM_ALL)
diff --git a/external/polyseed b/external/polyseed
new file mode 160000
index 000000000..bd79f5014
@@ -332,7 +148,7 @@ index 000000000..3de4596fb
@@ -0,0 +1 @@
+Subproject commit 3de4596fbe28956855df2ecb3c11c0bbc3535838
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9216bcaa5..c043ba150 100644
index 3335d3c21..06b708cf0 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -95,6 +95,7 @@ add_subdirectory(net)
@@ -341,8 +157,8 @@ index 9216bcaa5..c043ba150 100644
add_subdirectory(mnemonics)
+add_subdirectory(polyseed)
add_subdirectory(rpc)
add_subdirectory(seraphis_crypto)
if(NOT IOS)
add_subdirectory(serialization)
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
index 1414be1b2..414936a05 100644
--- a/src/cryptonote_basic/CMakeLists.txt
@@ -352,14 +168,14 @@ index 1414be1b2..414936a05 100644
cryptonote_format_utils_basic
device
+ polyseed_wrapper
oracle
${Boost_DATE_TIME_LIBRARY}
${Boost_PROGRAM_OPTIONS_LIBRARY}
${Boost_SERIALIZATION_LIBRARY}
diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp
index 4e87d4477..2d556f285 100644
--- a/src/cryptonote_basic/account.cpp
+++ b/src/cryptonote_basic/account.cpp
@@ -87,12 +87,16 @@ DISABLE_VS_WARNINGS(4244 4345)
@@ -89,12 +89,16 @@ DISABLE_VS_WARNINGS(4244 4345)
void account_keys::xor_with_key_stream(const crypto::chacha_key &key)
{
// encrypt a large enough byte stream with chacha20
@@ -377,16 +193,16 @@ index 4e87d4477..2d556f285 100644
for (crypto::secret_key &k: m_multisig_keys)
{
for (size_t i = 0; i < sizeof(crypto::secret_key); ++i)
@@ -150,6 +154,8 @@ DISABLE_VS_WARNINGS(4244 4345)
{
m_keys.m_spend_secret_key = crypto::secret_key();
@@ -153,6 +158,8 @@ DISABLE_VS_WARNINGS(4244 4345)
m_keys.s_master = m_keys.m_spend_secret_key;
m_keys.k_prove_spend = m_keys.m_spend_secret_key;
m_keys.m_multisig_keys.clear();
+ m_keys.m_polyseed = crypto::secret_key();
+ m_keys.m_passphrase.wipe();
}
//-----------------------------------------------------------------
void account_base::set_spend_key(const crypto::secret_key& spend_secret_key)
@@ -255,6 +261,21 @@ DISABLE_VS_WARNINGS(4244 4345)
@@ -260,6 +267,21 @@ DISABLE_VS_WARNINGS(4244 4345)
create_from_keys(address, fake, viewkey);
}
//-----------------------------------------------------------------
@@ -418,18 +234,18 @@ index 93d1d28f0..1f76febce 100644
#include "serialization/keyvalue_serialization.h"
+#include "polyseed/polyseed.hpp"
namespace cryptonote
{
@@ -45,6 +46,8 @@ namespace cryptonote
#include "carrot_core/account_secrets.h"
#include "carrot_core/address_utils.h"
@@ -52,6 +53,8 @@ namespace cryptonote
std::vector<crypto::secret_key> m_multisig_keys;
hw::device *m_device = &hw::get_device("default");
crypto::chacha_iv m_encryption_iv;
+ crypto::secret_key m_polyseed;
+ epee::wipeable_string m_passphrase; // Only used with polyseed
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(m_account_address)
@@ -53,6 +56,8 @@ namespace cryptonote
// carrot secret keys (minus k_v, which is shared with legacy k_v)
crypto::secret_key s_master;
@@ -71,6 +74,8 @@ namespace cryptonote
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(m_multisig_keys)
const crypto::chacha_iv default_iv{{0, 0, 0, 0, 0, 0, 0, 0}};
KV_SERIALIZE_VAL_POD_AS_BLOB_OPT(m_encryption_iv, default_iv)
@@ -438,7 +254,7 @@ index 93d1d28f0..1f76febce 100644
END_KV_SERIALIZE_MAP()
void encrypt(const crypto::chacha_key &key);
@@ -79,6 +84,7 @@ namespace cryptonote
@@ -99,6 +104,7 @@ namespace cryptonote
void create_from_device(hw::device &hwdev);
void create_from_keys(const cryptonote::account_public_address& address, const crypto::secret_key& spendkey, const crypto::secret_key& viewkey);
void create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey);
@@ -447,18 +263,18 @@ index 93d1d28f0..1f76febce 100644
const account_keys& get_keys() const;
std::string get_public_address_str(network_type nettype) const;
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index 8b5091a46..d9151e8d2 100644
index 82891b9de..26200bf34 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -219,6 +219,8 @@
@@ -265,6 +265,8 @@
#define DNS_BLOCKLIST_LIFETIME (86400 * 8)
+#define POLYSEED_COIN POLYSEED_WOWNERO
+#define POLYSEED_COIN POLYSEED_MONERO
+
//The limit is enough for the mandatory transaction content with 16 outputs (547 bytes),
//a custom tag (1 byte) and up to 32 bytes of custom data for each recipient.
// (1+32) + (1+1+16*32) + (1+16*32) = 1060
#define PRICING_RECORD_VALID_BLOCKS 10
#define PRICING_RECORD_VALID_TIME_DIFF_FROM_BLOCK 120 // seconds
diff --git a/src/polyseed/CMakeLists.txt b/src/polyseed/CMakeLists.txt
new file mode 100644
index 000000000..cca4eb746
@@ -998,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 556e2a8ce..704e5e148 100644
index 25ade04a7..51911bf99 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
@@ -1194,7 +1010,7 @@ index a223e1df9..28fcd36c9 100644
bool walletExists(const std::string &path) override;
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index e14d4d2fc..fd4094360 100644
index 765cefb32..806de969a 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -92,6 +92,7 @@ using namespace epee;
@@ -1202,15 +1018,15 @@ index e14d4d2fc..fd4094360 100644
#include "device_trezor/device_trezor.hpp"
#include "net/socks_connect.h"
+#include "polyseed/include/polyseed.h"
extern "C"
{
@@ -1278,7 +1279,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_enable_multisig(false),
#include "carrot_impl/format_utils.h"
#include "tx_builder.h"
#include "scanning_tools.h"
@@ -1273,7 +1274,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_send_change_back_to_subaddress(false),
m_pool_info_query_time(0),
m_has_ever_refreshed_from_node(false),
- m_allow_mismatched_daemon_version(true)
+ m_allow_mismatched_daemon_version(true),
- m_allow_mismatched_daemon_version(false)
+ m_allow_mismatched_daemon_version(false),
+ m_polyseed(false)
{
set_rpc_client_secret_key(rct::rct2sk(rct::skGen()));
@@ -1235,26 +1051,26 @@ index e14d4d2fc..fd4094360 100644
+//----------------------------------------------------------------------------------------------------
bool wallet2::get_multisig_seed(epee::wipeable_string& seed, const epee::wipeable_string &passphrase) const
{
bool ready;
@@ -4801,6 +4817,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const crypt
const multisig::multisig_account_status ms_status{get_multisig_status()};
@@ -5313,6 +5329,9 @@ boost::optional<wallet2::keys_file_data> wallet2::get_keys_file_data(const crypt
value2.SetInt(m_enable_multisig ? 1 : 0);
json.AddMember("enable_multisig", value2, json.GetAllocator());
+ value2.SetInt(m_polyseed ? 1 : 0);
+ json.AddMember("polyseed", value2, json.GetAllocator());
+
if (m_background_sync_type == BackgroundSyncCustomPassword && !background_keys_file && m_custom_background_key)
{
value.SetString(reinterpret_cast<const char*>(m_custom_background_key.get().data()), m_custom_background_key.get().size());
@@ -5040,6 +5059,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
m_enable_multisig = false;
m_allow_mismatched_daemon_version = true;
value2.SetInt(m_freeze_incoming_payments ? 1 : 0);
json.AddMember("freeze_incoming_payments", value2, json.GetAllocator());
@@ -5560,6 +5579,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
m_send_change_back_to_subaddress = false;
m_allow_mismatched_daemon_version = false;
m_custom_background_key = boost::none;
+ m_polyseed = false;
}
else if(json.IsObject())
{
@@ -5280,6 +5300,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
@@ -5804,6 +5824,9 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, background_sync_type, BackgroundSyncType, Int, false, BackgroundSyncOff);
m_background_sync_type = field_background_sync_type;
@@ -1264,7 +1080,7 @@ index e14d4d2fc..fd4094360 100644
// Load encryption key used to encrypt background cache
crypto::chacha_key custom_background_key;
m_custom_background_key = boost::none;
@@ -5599,6 +5622,48 @@ void wallet2::init_type(hw::device::device_type device_type)
@@ -6123,6 +6146,48 @@ void wallet2::init_type(hw::device::device_type device_type)
m_key_device_type = device_type;
}
@@ -1313,7 +1129,7 @@ index e14d4d2fc..fd4094360 100644
/*!
* \brief Generates a wallet or restores one. Assumes the multisig setup
* has already completed for the provided multisig info.
@@ -5726,7 +5791,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
@@ -6250,7 +6315,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
return retval;
}
@@ -1322,7 +1138,7 @@ index e14d4d2fc..fd4094360 100644
{
// -1 month for fluctuations in block time and machine date/time setup.
// avg seconds per block
@@ -5750,7 +5815,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
@@ -6274,7 +6339,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip
// the daemon is currently syncing.
// If we use the approximate height we subtract one month as
// a safety margin.
@@ -1331,19 +1147,25 @@ index e14d4d2fc..fd4094360 100644
uint64_t target_height = get_daemon_blockchain_target_height(err);
if (err.empty()) {
if (target_height < height)
@@ -13643,9 +13708,10 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
@@ -13926,7 +13991,7 @@ uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
return target_height;
}
-uint64_t wallet2::get_approximate_blockchain_height() const
+uint64_t wallet2::get_approximate_blockchain_height(uint64_t t) const
{
uint64_t approx_blockchain_height = m_nettype == TESTNET ? 0 : (time(NULL) - 1522624244)/307;
+ // uint64_t approx_blockchain_height = fork_block + ((t > 0 ? t : time(NULL)) - fork_time)/seconds_per_block;
if (m_nettype != MAINNET) return 0;
@@ -13937,7 +14002,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const
// avg seconds per block
const int seconds_per_block = DIFFICULTY_TARGET_V2;
// Calculated blockchain height
- uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block;
+ uint64_t approx_blockchain_height = fork_block + ((t > 0 ? t : time(NULL)) - fork_time)/seconds_per_block;
LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height);
return approx_blockchain_height;
}
@@ -15780,15 +15846,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin
@@ -16112,15 +16177,6 @@ bool wallet2::parse_uri(const std::string &uri, std::string &address, std::strin
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, uint8_t day)
{
@@ -1359,7 +1181,7 @@ index e14d4d2fc..fd4094360 100644
std::tm date = { 0, 0, 0, 0, 0, 0, 0, 0 };
date.tm_year = year - 1900;
date.tm_mon = month - 1;
@@ -15797,7 +15854,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui
@@ -16129,7 +16185,23 @@ uint64_t wallet2::get_blockchain_height_by_date(uint16_t year, uint8_t month, ui
{
throw std::runtime_error("month or day out of range");
}
@@ -1384,7 +1206,7 @@ index e14d4d2fc..fd4094360 100644
uint64_t height_min = 0;
uint64_t height_max = get_daemon_blockchain_height(err) - 1;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 746e2aeff..c165acb9d 100644
index a752f15b9..a619bdd15 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -72,6 +72,7 @@
@@ -1416,7 +1238,7 @@ index 746e2aeff..c165acb9d 100644
/*!
* \brief Generates a wallet or restores one.
* \param wallet_ Name of wallet file
@@ -1095,6 +1110,15 @@ private:
@@ -1126,6 +1141,15 @@ private:
bool is_deterministic() const;
bool get_seed(epee::wipeable_string& electrum_words, const epee::wipeable_string &passphrase = epee::wipeable_string()) const;
@@ -1430,8 +1252,8 @@ index 746e2aeff..c165acb9d 100644
+ bool get_polyseed(epee::wipeable_string& seed, epee::wipeable_string &passphrase) const;
+
/*!
* \brief Checks if light wallet. A light wallet sends view key to a server where the blockchain is scanned.
*/
* \brief Gets the seed language
*/
@@ -1562,8 +1586,8 @@ private:
/*!
* \brief Calculates the approximate blockchain height from current date/time.
@@ -1460,5 +1282,5 @@ index 746e2aeff..c165acb9d 100644
uint32_t m_multisig_threshold;
std::vector<crypto::public_key> m_multisig_signers;
--
2.48.0
2.48.1
@@ -1,7 +1,7 @@
From edc33fa98da3bc9e8e746a59f5e62b9001afb230 Mon Sep 17 00:00:00 2001
From 753d7eee48d8e9ab5950e48dc984cc1038c11dd1 Mon Sep 17 00:00:00 2001
From: tobtoht <tob@featherwallet.org>
Date: Tue, 12 Mar 2024 11:07:57 +0100
Subject: [PATCH 10/15] coin control
Subject: [PATCH 08/14] coin control
---
src/simplewallet/simplewallet.cpp | 2 +-
@@ -10,30 +10,52 @@ Subject: [PATCH 10/15] coin control
src/wallet/api/coins.h | 40 +++++++
src/wallet/api/coins_info.cpp | 122 ++++++++++++++++++++
src/wallet/api/coins_info.h | 71 ++++++++++++
src/wallet/api/wallet.cpp | 64 +++++++++-
src/wallet/api/wallet.cpp | 170 +++++++++++++++++++++------
src/wallet/api/wallet.h | 10 +-
src/wallet/api/wallet2_api.h | 52 ++++++++-
src/wallet/wallet2.cpp | 46 +++++++-
src/wallet/wallet2.h | 11 +-
11 files changed, 593 insertions(+), 19 deletions(-)
11 files changed, 667 insertions(+), 51 deletions(-)
create mode 100644 src/wallet/api/coins.cpp
create mode 100644 src/wallet/api/coins.h
create mode 100644 src/wallet/api/coins_info.cpp
create mode 100644 src/wallet/api/coins_info.h
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 83b56c3f4..12c38b8e1 100644
index 89691e9f7..b26817e52 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -6981,7 +6981,7 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
{
// figure out what tx will be necessary
auto ptx_vector = m_wallet->create_transactions_2(dsts, fake_outs_count, priority, extra,
- m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
+ m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs);
if (ptx_vector.empty())
{
@@ -7183,25 +7183,25 @@ bool simple_wallet::transfer_main(
switch (transfer_type) {
case Burn:
unlock_block = 0;
- ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::BURN, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
+ ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::BURN, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs);
break;
case Convert:
unlock_block = CONVERT_LOCK_PERIOD;
- ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::CONVERT, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
+ ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::CONVERT, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs);
break;
case Stake:
unlock_block = get_config(m_wallet->nettype()).STAKE_LOCK_PERIOD;
- ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::STAKE, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
+ ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::STAKE, fake_outs_count, unlock_block, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs);
break;
case TransferLocked:
unlock_block = locked_blocks;
- ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
+ ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, unlock_block /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs);
break;
default:
LOG_ERROR("Unknown transfer method, using default");
/* FALLTHRU */
case Transfer:
- ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, subtract_fee_from_outputs);
+ ptx_vector = m_wallet->create_transactions_2(dsts, source_asset, dest_asset, cryptonote::transaction_type::TRANSFER, fake_outs_count, 0 /* unlock_time */, priority, extra, m_current_subaddress_account, subaddr_indices, {}, subtract_fee_from_outputs);
break;
}
}
diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt
index af7948d8a..bb740e2ac 100644
--- a/src/wallet/api/CMakeLists.txt
@@ -65,7 +87,7 @@ new file mode 100644
index 000000000..ef12141cf
--- /dev/null
+++ b/src/wallet/api/coins.cpp
@@ -0,0 +1,186 @@
@@ -0,0 +1,194 @@
+#include "coins.h"
+#include "coins_info.h"
+#include "wallet.h"
@@ -131,6 +153,12 @@ index 000000000..ef12141cf
+ {
+ const tools::wallet2::transfer_details &td = m_wallet->m_wallet->get_transfer_details(i);
+
+ // Make a subaddress_index_extended from td.m_subaddr_index
+ carrot::subaddress_index_extended csub{
+ {td.m_subaddr_index.major, td.m_subaddr_index.minor},
+ td.is_carrot() ? carrot::AddressDeriveType::Carrot : carrot::AddressDeriveType::PreCarrot,
+ false};
+
+ auto ci = new CoinsInfoImpl();
+ ci->m_blockHeight = td.m_block_height;
+ ci->m_hash = string_tools::pod_to_hex(td.m_txid);
@@ -145,7 +173,7 @@ index 000000000..ef12141cf
+ ci->m_pkIndex = td.m_pk_index;
+ ci->m_subaddrIndex = td.m_subaddr_index.minor;
+ ci->m_subaddrAccount = td.m_subaddr_index.major;
+ ci->m_address = m_wallet->m_wallet->get_subaddress_as_str(td.m_subaddr_index); // todo: this is expensive, cache maybe?
+ ci->m_address = m_wallet->m_wallet->get_subaddress_as_str(csub); // todo: this is expensive, cache maybe?
+ ci->m_addressLabel = m_wallet->m_wallet->get_subaddress_label(td.m_subaddr_index);
+ ci->m_keyImage = string_tools::pod_to_hex(td.m_key_image);
+ ci->m_unlockTime = td.m_tx.unlock_time;
@@ -153,6 +181,8 @@ index 000000000..ef12141cf
+ ci->m_pubKey = string_tools::pod_to_hex(td.get_public_key());
+ ci->m_coinbase = td.m_tx.vin.size() == 1 && td.m_tx.vin[0].type() == typeid(cryptonote::txin_gen);
+ ci->m_description = m_wallet->m_wallet->get_tx_note(td.m_txid);
+ ci->m_asset = td.asset_type;
+ ci->m_type = td.m_tx.type;
+
+ m_rows.push_back(ci);
+ }
@@ -303,7 +333,7 @@ new file mode 100644
index 000000000..5f2c4e1e4
--- /dev/null
+++ b/src/wallet/api/coins_info.cpp
@@ -0,0 +1,122 @@
@@ -0,0 +1,132 @@
+#include "coins_info.h"
+
+using namespace std;
@@ -327,6 +357,7 @@ index 000000000..5f2c4e1e4
+ , m_subaddrIndex(0)
+ , m_unlockTime(0)
+ , m_unlocked(false)
+ , m_type(0)
+{
+
+}
@@ -423,6 +454,15 @@ index 000000000..5f2c4e1e4
+string CoinsInfoImpl::description() const {
+ return m_description;
+}
+
+string CoinsInfoImpl::asset() const {
+ return m_asset;
+}
+
+uint8_t CoinsInfoImpl::type() const {
+ return m_type;
+}
+
+} // namespace
+
+namespace Bitmonero = Monero;
@@ -431,7 +471,7 @@ new file mode 100644
index 000000000..c43e45abd
--- /dev/null
+++ b/src/wallet/api/coins_info.h
@@ -0,0 +1,71 @@
@@ -0,0 +1,75 @@
+#ifndef FEATHER_COINS_INFO_H
+#define FEATHER_COINS_INFO_H
+
@@ -470,6 +510,8 @@ index 000000000..c43e45abd
+ virtual std::string pubKey() const override;
+ virtual bool coinbase() const override;
+ virtual std::string description() const override;
+ virtual std::string asset() const override;
+ virtual uint8_t type() const override;
+
+private:
+ uint64_t m_blockHeight;
@@ -493,7 +535,9 @@ index 000000000..c43e45abd
+ std::string m_pubKey;
+ bool m_coinbase;
+ std::string m_description;
+
+ std::string m_asset;
+ uint8_t m_type;
+
+ friend class CoinsImpl;
+
+};
@@ -504,10 +548,10 @@ index 000000000..c43e45abd
+
+#endif //FEATHER_COINS_INFO_H
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 704e5e148..e69910e69 100644
index 4b0a26a6b..644cf503b 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -35,6 +35,7 @@
@@ -36,6 +36,7 @@
#include "transaction_history.h"
#include "address_book.h"
#include "subaddress.h"
@@ -515,7 +559,7 @@ index 704e5e148..e69910e69 100644
#include "subaddress_account.h"
#include "common_defines.h"
#include "common/util.h"
@@ -473,6 +474,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
@@ -444,6 +445,7 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds)
m_wallet->set_refresh_enabled(false);
m_addressBook.reset(new AddressBookImpl(this));
m_subaddress.reset(new SubaddressImpl(this));
@@ -523,111 +567,241 @@ index 704e5e148..e69910e69 100644
m_subaddressAccount.reset(new SubaddressAccountImpl(this));
@@ -2046,7 +2048,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat
@@ -2018,7 +2020,7 @@ PendingTransaction *WalletImpl::createAuditTransaction(
// - unconfirmed_transfer_details;
// - confirmed_transfer_details)
-PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<string> &dst_addr, const string &payment_id, optional<std::vector<uint64_t>> amount, uint32_t mixin_count, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<string> &dst_addr, const string &payment_id, optional<std::vector<uint64_t>> amount, uint32_t mixin_count, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::set<std::string> &preferred_inputs)
-PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transaction_type &tx_type, const std::vector<string> &dst_addr, const string &payment_id, optional<std::vector<uint64_t>> amount, uint32_t mixin_count, const std::string &asset_type, const bool is_return, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transaction_type &tx_type, const std::vector<string> &dst_addr, const string &payment_id, optional<std::vector<uint64_t>> amount, uint32_t mixin_count, const std::string &asset_type, const bool is_return, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::set<std::string> &preferred_inputs)
{
clearStatus();
@@ -2084,6 +2086,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
@@ -2057,55 +2059,114 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
break;
}
}
bool error = false;
+ uint64_t amountSum = 0;
for (size_t i = 0; i < dst_addr.size() && !error; i++) {
if(!cryptonote::get_account_address_from_str(info, m_wallet->nettype(), dst_addr[i])) {
// TODO: copy-paste 'if treating as an address fails, try as url' from simplewallet.cpp:1982
@@ -2105,6 +2108,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
de.original = dst_addr[i];
de.addr = info.address;
de.amount = (*amount)[i];
+ amountSum += (*amount)[i];
de.is_subaddress = info.is_subaddress;
de.is_integrated = info.has_payment_id;
dsts.push_back(de);
@@ -2115,6 +2119,51 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
- bool error = false;
- for (size_t i = 0; i < dst_addr.size() && !error; i++) {
- if(!cryptonote::get_account_address_from_str(info, m_wallet->nettype(), dst_addr[i])) {
- // TODO: copy-paste 'if treating as an address fails, try as url' from simplewallet.cpp:1982
- setStatusError(tr("Invalid destination address"));
- error = true;
- break;
- }
- if (info.has_payment_id) {
- if (!extra_nonce.empty()) {
- setStatusError(tr("a single transaction cannot use more than one payment id"));
+ uint64_t max_coin_control_input = 0;
+ uint64_t max_frozen_input = 0;
+ try {
+ bool error = false;
+ uint64_t amountSum = 0;
+ for (size_t i = 0; i < dst_addr.size() && !error; i++) {
+ if(!cryptonote::get_account_address_from_str(info, m_wallet->nettype(), dst_addr[i])) {
+ // TODO: copy-paste 'if treating as an address fails, try as url' from simplewallet.cpp:1982
+ setStatusError(tr("Invalid destination address"));
error = true;
break;
}
- set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id);
+ if (info.has_payment_id) {
+ if (!extra_nonce.empty()) {
+ setStatusError(tr("a single transaction cannot use more than one payment id"));
+ error = true;
+ break;
+ }
+ set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id);
+ }
+
+ if (amount) {
+ cryptonote::tx_destination_entry de;
+ de.original = dst_addr[i];
+ de.addr = info.address;
+ de.amount = (*amount)[i];
+ de.asset_type = asset_type;
+ amountSum += (*amount)[i];
+ de.is_subaddress = info.is_subaddress;
+ de.is_integrated = info.has_payment_id;
+ de.is_return = is_return;
+ dsts.push_back(de);
+ } else {
+ if (subaddr_indices.empty()) {
+ for (uint32_t index = 0; index < m_wallet->get_num_subaddresses(subaddr_account); ++index)
+ subaddr_indices.insert(index);
+ }
+ }
}
}
+ // uint64_t maxAllowedSpend = m_wallet->unlocked_balance(subaddr_account, true);
+ // if (maxAllowedSpend < amountSum) {
+ // error = true;
+ // setStatusError(tr("Amount you are trying to spend is larger than unlocked amount"));
+ // break;
+ // }
+ std::vector<crypto::key_image> preferred_input_list;
+ if (!preferred_inputs.empty()) {
+ LOG_ERROR("empty");
- if (amount) {
- cryptonote::tx_destination_entry de;
- de.original = dst_addr[i];
- de.addr = info.address;
- de.amount = (*amount)[i];
- de.asset_type = asset_type;
- de.is_subaddress = info.is_subaddress;
- de.is_integrated = info.has_payment_id;
- de.is_return = is_return;
- dsts.push_back(de);
- } else {
- if (subaddr_indices.empty()) {
- for (uint32_t index = 0; index < m_wallet->get_num_subaddresses(subaddr_account); ++index)
- subaddr_indices.insert(index);
+ // uint64_t maxAllowedSpend = m_wallet->unlocked_balance(subaddr_account, true);
+ // if (maxAllowedSpend < amountSum) {
+ // error = true;
+ // setStatusError(tr("Amount you are trying to spend is larger than unlocked amount"));
+ // break;
+ // }
+ std::vector<crypto::key_image> preferred_input_list;
+ if (!preferred_inputs.empty()) {
+ LOG_ERROR("not empty");
+
+ for (const auto &public_key : preferred_inputs) {
+ crypto::key_image keyImage;
+ bool r = epee::string_tools::hex_to_pod(public_key, keyImage);
+ if (!r) {
+ error = true;
+ setStatusError(tr("failed to parse key image"));
+ break;
+ }
+ if (m_wallet->frozen(keyImage)) {
+ error = true;
+ setStatusError(tr("refusing to spend frozen coin"));
+ break;
+ for (const auto &public_key : preferred_inputs) {
+ crypto::key_image keyImage;
+ bool r = epee::string_tools::hex_to_pod(public_key, keyImage);
+ if (!r) {
+ error = true;
+ setStatusError(tr("failed to parse key image"));
+ break;
+ }
+ if (m_wallet->frozen(keyImage)) {
+ error = true;
+ setStatusError(tr("refusing to spend frozen coin"));
+ break;
}
+
+ for (size_t i = 0; i < m_wallet->get_num_transfer_details(); ++i) {
+ const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(i);
+ if (td.m_key_image == keyImage) {
+ max_coin_control_input += td.amount();
+ }
+ if (td.m_frozen) {
+ max_frozen_input += td.amount();
+ }
+ }
+
+ preferred_input_list.push_back(keyImage);
+ }
+ LOG_ERROR("not empty");
+
+ preferred_input_list.push_back(keyImage);
+ }
+ } else {
+ LOG_ERROR("not empty");
+
+ boost::shared_lock<boost::shared_mutex> transfers_lock(m_wallet->m_transfers_mutex);
+ for (size_t i = 0; i < m_wallet->get_num_transfer_details(); ++i) {
+ const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(i);
+ LOG_ERROR("COIN: " << i << ": " << td.amount() << "; "<<td.m_spent << ";" << td.m_frozen << ";" << m_wallet->frozen(td));
+ if (td.m_spent) continue;
+ LOG_ERROR("is frozen");
+ if (!td.m_frozen) {
+ LOG_ERROR("isn't:");
+ LOG_ERROR("hash: " << td.m_key_image << "; " << td.amount());
+ preferred_input_list.push_back(td.m_key_image);
+ boost::shared_lock<boost::shared_mutex> transfers_lock(m_wallet->m_transfers_mutex);
+ for (size_t i = 0; i < m_wallet->get_num_transfer_details(); ++i) {
+ const tools::wallet2::transfer_details &td = m_wallet->get_transfer_details(i);
+ LOG_ERROR("COIN: " << i << ": " << td.amount() << "; "<<td.m_spent << ";" << td.m_frozen << ";" << m_wallet->frozen(td));
+ if (td.m_spent) continue;
+ LOG_ERROR("is frozen");
+ if (!td.m_frozen) {
+ LOG_ERROR("isn't:");
+ LOG_ERROR("hash: " << td.m_key_image << "; " << td.amount());
+ preferred_input_list.push_back(td.m_key_image);
+ }
+ }
+ }
+ }
+ for (const auto &de : preferred_input_list) {
+ LOG_ERROR("preferred input: " << de);
+ }
if (error) {
break;
}
@@ -2129,11 +2178,11 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
if (amount) {
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, fake_outs_count,
adjusted_priority,
- extra, subaddr_account, subaddr_indices);
+ extra, subaddr_account, subaddr_indices, preferred_input_list);
} else {
transaction->m_pending_tx = m_wallet->create_transactions_all(0, info.address, info.is_subaddress, 1, fake_outs_count,
adjusted_priority,
- extra, subaddr_account, subaddr_indices);
+ extra, subaddr_account, subaddr_indices, preferred_input_list);
+ for (const auto &de : preferred_input_list) {
+ LOG_ERROR("preferred input: " << de);
+ }
+ if (error) {
+ break;
+ }
+ if (!extra_nonce.empty() && !add_extra_nonce_to_tx_extra(extra, extra_nonce)) {
+ setStatusError(tr("failed to set up payment id, though it was decoded correctly"));
+ break;
}
pendingTxPostProcess(transaction);
- }
- if (error) {
- break;
- }
- if (!extra_nonce.empty() && !add_extra_nonce_to_tx_extra(extra, extra_nonce)) {
- setStatusError(tr("failed to set up payment id, though it was decoded correctly"));
- break;
- }
- try {
size_t fake_outs_count = mixin_count > 0 ? mixin_count : m_wallet->default_mixin();
fake_outs_count = m_wallet->adjust_mixin(mixin_count);
@@ -2214,10 +2263,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector<stri
if (amount) {
transaction->m_pending_tx = m_wallet->create_transactions_2(dsts, asset_type, asset_type, converted_tx_type, fake_outs_count, 0 /* unlock_time */,
adjusted_priority,
- extra, subaddr_account, subaddr_indices);
+ extra, subaddr_account, subaddr_indices, preferred_input_list);
} else {
std::vector<tools::wallet2::pending_tx> m_pending_txs;
for (const auto subaddr_index : subaddr_indices) {
@@ -2127,7 +2188,8 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
adjusted_priority,
extra,
subaddr_account,
- std::set<uint32_t> {subaddr_index}
+ std::set<uint32_t> {subaddr_index},
+ preferred_input_list
);
m_pending_txs.insert(m_pending_txs.end(), result.begin(), result.end());
@@ -2165,6 +2227,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
writer << boost::format(tr("not enough money to transfer, available only %s, sent amount %s")) %
print_money(e.available()) %
print_money(e.tx_amount());
+ if (max_coin_control_input != 0 &&
+ max_coin_control_input != e.available()) {
+ writer << std::endl << boost::format(tr("In addition, coin control was enabled for this transaction, limiting available balance to %s. Make sure that you have enough outputs selected in coin control")) %
+ print_money(max_coin_control_input);
+ }
+ if (max_frozen_input != 0 &&
+ max_frozen_input != e.available()) {
+ writer << std::endl << boost::format(tr("In addition, some a total of %s is frozen. Make sure that you have enough outputs unforzen outputs in coin control")) %
+ print_money(max_frozen_input);
+ }
setStatusError(writer.str());
} catch (const tools::error::not_enough_money& e) {
std::ostringstream writer;
@@ -2172,6 +2244,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
writer << boost::format(tr("not enough money to transfer, overall balance only %s, sent amount %s")) %
print_money(e.available()) %
print_money(e.tx_amount());
+ if (max_coin_control_input != 0 &&
+ max_coin_control_input != e.available()) {
+ writer << std::endl << boost::format(tr("In addition, coin control was enabled for this transaction, limiting available balance to %s. Make sure that you have enough outputs selected in coin control")) %
+ print_money(max_coin_control_input);
+ }
+ if (max_frozen_input != 0 &&
+ max_frozen_input != e.available()) {
+ writer << std::endl << boost::format(tr("In addition, some a total of %s is frozen. Make sure that you have enough outputs unforzen outputs in coin control")) %
+ print_money(max_frozen_input);
+ }
setStatusError(writer.str());
} catch (const tools::error::tx_not_possible& e) {
std::ostringstream writer;
@@ -2179,6 +2261,16 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
print_money(e.tx_amount() + e.fee()) %
print_money(e.tx_amount()) %
print_money(e.fee());
+ if (max_coin_control_input != 0 &&
+ max_coin_control_input != e.available()) {
+ writer << std::endl << boost::format(tr("In addition, coin control was enabled for this transaction, limiting available balance to %s. Make sure that you have enough outputs selected in coin control")) %
+ print_money(max_coin_control_input);
+ }
+ if (max_frozen_input != 0 &&
+ max_frozen_input != e.available()) {
+ writer << std::endl << boost::format(tr("In addition, some a total of %s is frozen. Make sure that you have enough outputs unforzen outputs in coin control")) %
+ print_money(max_frozen_input);
+ }
setStatusError(writer.str());
} catch (const tools::error::not_enough_outs_to_mix& e) {
std::ostringstream writer;
@@ -2222,10 +2304,10 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const Monero::transact
}
PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, optional<uint64_t> amount, uint32_t mixin_count,
- PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+ PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::set<std::string> &preferred_inputs)
- const std::string &asset_type, const bool is_return, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+ const std::string &asset_type, const bool is_return, PendingTransaction::Priority priority, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::set<std::string> &preferred_inputs)
{
- return createTransactionMultDest(std::vector<string> {dst_addr}, payment_id, amount ? (std::vector<uint64_t> {*amount}) : (optional<std::vector<uint64_t>>()), mixin_count, priority, subaddr_account, subaddr_indices);
+ return createTransactionMultDest(std::vector<string> {dst_addr}, payment_id, amount ? (std::vector<uint64_t> {*amount}) : (optional<std::vector<uint64_t>>()), mixin_count, priority, subaddr_account, subaddr_indices, preferred_inputs);
- return createTransactionMultDest(Monero::transaction_type::TRANSFER, std::vector<string> {dst_addr}, payment_id, amount ? (std::vector<uint64_t> {*amount}) : (optional<std::vector<uint64_t>>()), mixin_count, asset_type, is_return, priority, subaddr_account, subaddr_indices);
+ return createTransactionMultDest(Monero::transaction_type::TRANSFER, std::vector<string> {dst_addr}, payment_id, amount ? (std::vector<uint64_t> {*amount}) : (optional<std::vector<uint64_t>>()), mixin_count, asset_type, is_return, priority, subaddr_account, subaddr_indices, preferred_inputs);
}
PendingTransaction *WalletImpl::createSweepUnmixableTransaction()
@@ -2342,6 +2391,11 @@ AddressBook *WalletImpl::addressBook()
@@ -2350,6 +2442,11 @@ AddressBook *WalletImpl::addressBook()
return m_addressBook.get();
}
@@ -651,20 +825,21 @@ index 32e12284b..a82f270e4 100644
class SubaddressAccountImpl;
struct Wallet2CallbackImpl;
@@ -167,12 +168,14 @@ public:
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) override;
+ std::set<uint32_t> subaddr_indices = {},
+ const std::set<std::string> &preferred_inputs = {}) override;
@@ -167,13 +168,15 @@ public:
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) override;
+ std::set<uint32_t> subaddr_indices = {},
+ const std::set<std::string> &preferred_inputs = {}) override;
PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id,
optional<uint64_t> amount, uint32_t mixin_count,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) override;
+ std::set<uint32_t> subaddr_indices = {},
+ const std::set<std::string> &preferred_inputs = {}) override;
optional<uint64_t> amount, uint32_t mixin_count,
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) override;
+ std::set<uint32_t> subaddr_indices = {},
+ const std::set<std::string> &preferred_inputs = {}) override;
virtual PendingTransaction * createSweepUnmixableTransaction() override;
bool submitTransaction(const std::string &fileName) override;
bool submitTransactionUR(const std::string &input) override;
@@ -696,7 +871,7 @@ diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index be1c3704e..013b5bcba 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -263,6 +263,51 @@ struct AddressBook
@@ -263,6 +263,53 @@ struct AddressBook
virtual int lookupPaymentID(const std::string &payment_id) const = 0;
};
@@ -728,6 +903,8 @@ index be1c3704e..013b5bcba 100644
+ virtual std::string pubKey() const = 0;
+ virtual bool coinbase() const = 0;
+ virtual std::string description() const = 0;
+ virtual std::string asset() const = 0;
+ virtual uint8_t type() const = 0;
+};
+
+struct Coins
@@ -748,18 +925,18 @@ index be1c3704e..013b5bcba 100644
struct SubaddressRow {
public:
SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label):
@@ -856,7 +901,8 @@ struct Wallet
optional<std::vector<uint64_t>> amount, uint32_t mixin_count,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) = 0;
+ std::set<uint32_t> subaddr_indices = {},
+ const std::set<std::string> &preferred_inputs = {}) = 0;
@@ -940,7 +985,8 @@ struct Wallet
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) = 0;
+ std::set<uint32_t> subaddr_indices = {},
+ const std::set<std::string> &preferred_inputs = {}) = 0;
/*!
* \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored
@@ -875,7 +921,8 @@ struct Wallet
optional<uint64_t> amount, uint32_t mixin_count,
const std::string &asset_type, const bool is_return,
PendingTransaction::Priority = PendingTransaction::Priority_Low,
uint32_t subaddr_account = 0,
- std::set<uint32_t> subaddr_indices = {}) = 0;
@@ -777,10 +954,10 @@ index be1c3704e..013b5bcba 100644
virtual SubaddressAccount * subaddressAccount() = 0;
virtual void setListener(WalletListener *) = 0;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index fd4094360..be3096675 100644
index 806de969a..8720e18b1 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -2103,12 +2103,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const
@@ -2100,12 +2100,21 @@ bool wallet2::frozen(const multisig_tx_set& txs) const
return false;
}
@@ -802,7 +979,7 @@ index fd4094360..be3096675 100644
void wallet2::thaw(const crypto::key_image &ki)
{
thaw(get_transfer_details(ki));
@@ -2119,6 +2128,18 @@ bool wallet2::frozen(const crypto::key_image &ki) const
@@ -2116,6 +2125,18 @@ bool wallet2::frozen(const crypto::key_image &ki) const
return frozen(get_transfer_details(ki));
}
//----------------------------------------------------------------------------------------------------
@@ -821,33 +998,25 @@ index fd4094360..be3096675 100644
size_t wallet2::get_transfer_details(const crypto::key_image &ki) const
{
for (size_t idx = 0; idx < m_transfers.size(); ++idx)
@@ -2532,6 +2553,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
uint64_t amount = tx.vout[o].amount ? tx.vout[o].amount : tx_scan_info[o].amount;
if (!pool)
{
+ boost::unique_lock<boost::shared_mutex> lock(m_transfers_mutex);
m_transfers.push_back(transfer_details{});
transfer_details& td = m_transfers.back();
td.m_block_height = height;
@@ -2635,6 +2657,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
uint64_t extra_amount = amount - burnt;
if (!pool)
{
+ boost::unique_lock<boost::shared_mutex> lock(m_transfers_mutex);
transfer_details &td = m_transfers[kit->second];
td.m_block_height = height;
td.m_internal_output_index = o;
@@ -10506,7 +10529,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
@@ -2621,6 +2643,7 @@ void wallet2::process_new_scanned_transaction(const crypto::hash &txid, const cryp
continue;
// update m_transfers view-incoming scan info, and default values
+ boost::unique_lock<boost::shared_mutex> lock(m_transfers_mutex);
transfer_details& td = m_transfers.emplace_back();
td.m_block_height = height;
td.m_internal_output_index = local_output_index;
@@ -11031,7 +11054,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
LOG_PRINT_L2("transfer_selected_rct done");
}
-std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices)
+std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
-std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices, const std::string& asset_type)
+std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices, const std::string& asset_type, const std::vector<crypto::key_image>& preferred_input_list)
{
std::vector<size_t> picks;
float current_output_relatdness = 1.0f;
@@ -10517,6 +10540,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t i = 0; i < m_transfers.size(); ++i)
@@ -11048,6 +11071,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t i: m_transfers_indices[asset_type])
{
const transfer_details& td = m_transfers[i];
+ if (!is_preferred_input(preferred_input_list, td.m_key_image)) {
@@ -856,37 +1025,37 @@ index fd4094360..be3096675 100644
if (!is_spent(td, false) && !td.m_frozen && td.is_rct() && td.amount() >= needed_money && 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)
@@ -10537,6 +10563,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t i = 0; i < m_transfers.size(); ++i)
@@ -11069,6 +11095,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
{
const transfer_details& td = m_transfers[i];
size_t idx = *i;
const transfer_details& td = m_transfers[idx];
+ if (!is_preferred_input(preferred_input_list, td.m_key_image)) {
+ continue;
+ }
if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && 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)
@@ -10548,6 +10577,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
for (size_t j = i + 1; j < m_transfers.size(); ++j)
@@ -11084,6 +11113,9 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
{
const transfer_details& td2 = m_transfers[j];
size_t idx2 = *j;
const transfer_details& td2 = m_transfers[idx2];
+ if (!is_preferred_input(preferred_input_list, td2.m_key_image)) {
+ continue;
+ }
if (td2.amount() > m_ignore_outputs_above || td2.amount() < m_ignore_outputs_below)
{
MDEBUG("Ignoring output " << j << " of amount " << print_money(td2.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
@@ -11120,7 +11152,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
MDEBUG("Ignoring output " << idx2 << " of amount " << print_money(td2.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
@@ -11125,7 +11157,7 @@ bool wallet2::light_wallet_key_image_is_ours(const crypto::key_image& key_image,
// This system allows for sending (almost) the entire balance, since it does
// not generate spurious change in all txes, thus decreasing the instantaneous
// usable balance.
-std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list, const unique_index_container& subtract_fee_from_outputs)
-std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const std::string& source_asset, const std::string& dest_asset, const cryptonote::transaction_type tx_type, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const std::string& source_asset, const std::string& dest_asset, const cryptonote::transaction_type tx_type, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list, const unique_index_container& subtract_fee_from_outputs)
{
//ensure device is let in NONE mode in any case
hw::device &hwdev = m_account.get_device();
@@ -11328,6 +11360,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
for (size_t i = 0; i < m_transfers.size(); ++i)
@@ -11333,6 +11365,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
for (size_t i: m_transfers_indices[source_asset])
{
const transfer_details& td = m_transfers[i];
+ if (!is_preferred_input(preferred_input_list, td.m_key_image)) {
@@ -895,27 +1064,28 @@ index fd4094360..be3096675 100644
if (m_ignore_fractional_outputs && td.amount() < fractional_threshold)
{
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
@@ -11419,7 +11454,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
@@ -11528,7 +11563,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
// will get us a known fee.
uint64_t estimated_fee = estimate_fee(use_per_byte_fee, use_rct, 2, fake_outs_count, 2, extra.size(), bulletproof, clsag, bulletproof_plus, use_view_tags, base_fee, fee_quantization_mask);
total_needed_money = needed_money + (subtract_fee_from_outputs.size() ? 0 : estimated_fee);
- preferred_inputs = pick_preferred_rct_inputs(total_needed_money, subaddr_account, subaddr_indices);
+ preferred_inputs = pick_preferred_rct_inputs(total_needed_money, subaddr_account, subaddr_indices, preferred_input_list);
- preferred_inputs = pick_preferred_rct_inputs(total_needed_money, subaddr_account, subaddr_indices, source_asset);
+ preferred_inputs = pick_preferred_rct_inputs(total_needed_money, subaddr_account, subaddr_indices, source_asset, preferred_input_list);
if (!preferred_inputs.empty())
{
string s;
@@ -11898,7 +11933,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
@@ -12022,7 +12057,7 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, c
return true;
}
-std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
-std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, cryptonote::transaction_type tx_type, const std::string &asset_type, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices)
+std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below, cryptonote::transaction_type tx_type, const std::string &asset_type, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list)
{
std::vector<size_t> unused_transfers_indices;
std::vector<size_t> unused_dust_indices;
@@ -11927,6 +11962,9 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
for (size_t i = 0; i < m_transfers.size(); ++i)
const bool do_carrot_tx_construction = use_fork_rules(HF_VERSION_CARROT);
if (do_carrot_tx_construction)
@@ -12056,7 +12091,10 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
for (const auto& i: m_transfers_indices[asset_type])
{
//size_t i = m_transfers_indices[asset_type][idx];
const transfer_details& td = m_transfers[i];
+ if (!is_preferred_input(preferred_input_list, td.m_key_image)) {
+ continue;
@@ -924,29 +1094,29 @@ index fd4094360..be3096675 100644
{
MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold));
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index c165acb9d..6b103d9c2 100644
index a619bdd15..4f324c238 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1216,8 +1216,8 @@ private:
@@ -1286,8 +1286,8 @@ private:
bool parse_unsigned_tx_from_str(const std::string &unsigned_tx_st, unsigned_tx_set &exported_txs) const;
bool load_tx(const std::string &signed_filename, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set&)> accept_func = NULL);
bool parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func);
- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
- std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
+ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
+ std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, uint32_t priority, const std::vector<uint8_t>& extra);
bool sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, const std::vector<cryptonote::tx_destination_entry>& dsts, const unique_index_container& subtract_fee_from_outputs = {}) const;
@@ -1569,6 +1569,7 @@ private:
- std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const std::string& source_asset, const std::string& dest_asset, const cryptonote::transaction_type tx_type, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
- std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, cryptonote::transaction_type tx_type, const std::string& asset_type, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices);
+ std::vector<wallet2::pending_tx> create_transactions_2(std::vector<cryptonote::tx_destination_entry> dsts, const std::string& source_asset, const std::string& dest_asset, const cryptonote::transaction_type tx_type, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {}, const unique_index_container& subtract_fee_from_outputs = {}); // pass subaddr_indices by value on purpose
+ std::vector<wallet2::pending_tx> create_transactions_all(uint64_t below, cryptonote::transaction_type tx_type, const std::string& asset_type, const cryptonote::account_public_address &address, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra, uint32_t subaddr_account, std::set<uint32_t> subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list = {});
std::vector<wallet2::pending_tx> create_transactions_single(const crypto::key_image &ki, const cryptonote::account_public_address &address, const cryptonote::transaction_type tx_type, bool is_subaddress, const size_t outputs, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
std::vector<wallet2::pending_tx> create_transactions_return(std::vector<size_t> transfers_indices);
std::vector<wallet2::pending_tx> create_transactions_from(const cryptonote::account_public_address &address, const cryptonote::transaction_type tx_type, const std::string& asset_type, bool is_subaddress, const size_t outputs, std::vector<size_t> unused_transfers_indices, std::vector<size_t> unused_dust_indices, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector<uint8_t>& extra);
@@ -1694,6 +1694,7 @@ private:
uint64_t get_num_rct_outputs();
size_t get_num_transfer_details() const { return m_transfers.size(); }
const transfer_details &get_transfer_details(size_t idx) const;
+ size_t get_transfer_details(const crypto::public_key &pk) const;
uint8_t estimate_current_hard_fork(const uint64_t height = 0) const;
uint8_t get_current_hard_fork();
void get_hard_fork_info(uint8_t version, uint64_t &earliest_height);
@@ -1800,7 +1801,9 @@ private:
@@ -1835,7 +1836,9 @@ private:
void freeze(size_t idx);
void thaw(size_t idx);
bool frozen(size_t idx) const;
@@ -956,24 +1126,24 @@ index c165acb9d..6b103d9c2 100644
void thaw(const crypto::key_image &ki);
bool frozen(const crypto::key_image &ki) const;
bool frozen(const transfer_details &td) const;
@@ -1841,6 +1844,8 @@ private:
@@ -1876,6 +1879,8 @@ private:
static std::string get_default_daemon_address() { CRITICAL_REGION_LOCAL(default_daemon_address_lock); return default_daemon_address; }
+ boost::shared_mutex m_transfers_mutex;
+
private:
/*!
* \brief Stores wallet information to wallet file.
@@ -1912,7 +1917,7 @@ private:
bool get_pricing_record(oracle::pricing_record& pr, const uint64_t height);
bool get_circulating_supply(std::vector<std::pair<std::string, std::string>> &amounts);
bool get_yield_info(std::vector<cryptonote::yield_block_info>& ybi_data);
@@ -1962,7 +1967,7 @@ private:
std::vector<uint64_t> get_unspent_amounts_vector(bool strict);
uint64_t get_dynamic_base_fee_estimate();
float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const;
- std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices);
+ std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices, const std::vector<crypto::key_image>& preferred_input_list);
- std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices, const std::string& asset_type);
+ std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices, const std::string& asset_type, const std::vector<crypto::key_image>& preferred_input_list);
void set_spent(size_t idx, uint64_t height);
void set_spent(const crypto::key_image &ki, const uint64_t height);
void set_unspent(size_t idx);
bool is_spent(const transfer_details &td, bool strict = true) const;
--
2.48.0
2.48.1
@@ -1,7 +1,7 @@
From 96911b156ad9cfef2ebf2809a393492e87ab7607 Mon Sep 17 00:00:00 2001
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 11/15] Add hex encoding and tx key getter for
Subject: [PATCH 09/14] Add hex encoding and tx key getter for
PendingTransction in wallet api.
---
@@ -64,5 +64,5 @@ index 013b5bcba..f421fdc05 100644
/**
--
2.48.0
2.48.1
@@ -1,7 +1,7 @@
From ad28016bf3cfd11242dc14472389f7a006c73dcf Mon Sep 17 00:00:00 2001
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 12/15] Add recoverDeterministicWalletFromSpendKey
Subject: [PATCH 10/14] 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 e69910e69..e650e6044 100644
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
@@ -149,5 +149,5 @@ index 28fcd36c9..be3ff8184 100644
const std::string &password,
NetworkType nettype,
--
2.48.0
2.48.1
@@ -1,7 +1,7 @@
From f8b3055a79c929dc167d20d4874ab20b0a51d49d Mon Sep 17 00:00:00 2001
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 13/15] add monero submodule support
Subject: [PATCH 11/14] add monero submodule support
---
CMakeLists.txt | 6 +++---
@@ -10,11 +10,11 @@ Subject: [PATCH 13/15] add monero submodule support
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 96056e324..1383e630a 100644
index f0630ef9b..9406e57b4 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -223,9 +223,9 @@ function(forbid_undefined_symbols)
cmake_minimum_required(VERSION 3.1)
@@ -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(); }")
@@ -25,7 +25,7 @@ index 96056e324..1383e630a 100644
endif()
add_library(l0 SHARED incorrect_source.cpp)
add_library(l1 MODULE incorrect_source.cpp)
@@ -391,7 +391,7 @@ else()
@@ -390,7 +390,7 @@ else()
endif()
list(INSERT CMAKE_MODULE_PATH 0
@@ -48,18 +48,18 @@ index 7ecf5f610..89fb9d167 100644
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 21e69ea0e..d9bc5dda3 100644
index 3188c88db..9fbdb3c05 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -1162,7 +1162,7 @@ namespace tools
@@ -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, mixin, priority, extra, req.account_index, req.subaddr_indices, req.subtract_fee_from_outputs);
+ std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_2(dsts, mixin, 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);
+ 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.0
2.48.1
@@ -1,7 +1,7 @@
From a707d5fc2aa9d387857381e7ebc4a68c1d245a00 Mon Sep 17 00:00:00 2001
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 14/15] fix iOS depends build
Subject: [PATCH 12/14] fix iOS depends build
---
CMakeLists.txt | 4 ----
@@ -11,20 +11,20 @@ Subject: [PATCH 14/15] fix iOS depends build
4 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1383e630a..b8782570d 100644
index 9406e57b4..1eac121db 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -39,10 +39,6 @@ include(CheckLibraryExists)
include(CheckFunctionExists)
endif()
include(FindPythonInterp)
-if (IOS)
- INCLUDE(CmakeLists_IOS.txt)
-endif()
-
cmake_minimum_required(VERSION 3.5)
message(STATUS "CMake version ${CMAKE_VERSION}")
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
@@ -60,7 +60,7 @@ index 414936a05..81c81767f 100644
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 83bea8b5b..dfb4b5c5a 100644
index 71b8f78cc..0f53f024e 100644
--- a/src/cryptonote_basic/miner.cpp
+++ b/src/cryptonote_basic/miner.cpp
@@ -45,7 +45,7 @@
@@ -72,7 +72,7 @@ index 83bea8b5b..dfb4b5c5a 100644
#include <sys/times.h>
#include <IOKit/IOKitLib.h>
#include <IOKit/ps/IOPSKeys.h>
@@ -971,7 +971,7 @@ namespace cryptonote
@@ -883,7 +883,7 @@ namespace cryptonote
return true;
@@ -81,7 +81,7 @@ index 83bea8b5b..dfb4b5c5a 100644
mach_msg_type_number_t count;
kern_return_t status;
@@ -1037,7 +1037,7 @@ namespace cryptonote
@@ -949,7 +949,7 @@ namespace cryptonote
return true;
}
@@ -90,7 +90,7 @@ index 83bea8b5b..dfb4b5c5a 100644
struct tms tms;
if ( times(&tms) != (clock_t)-1 )
@@ -1066,7 +1066,7 @@ namespace cryptonote
@@ -978,7 +978,7 @@ namespace cryptonote
return boost::logic::tribool(power_status.ACLineStatus != 1);
}
@@ -100,5 +100,5 @@ index 83bea8b5b..dfb4b5c5a 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.0
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
@@ -1,17 +1,17 @@
From d47284456194c6d99698b28908d753acf1a64010 Mon Sep 17 00:00:00 2001
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] change earliest fork height message
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 d060bf95b..9c1574c02 100644
index 8720e18b1..69da11d9c 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -12354,7 +12354,7 @@ bool wallet2::use_fork_rules(uint8_t version, int64_t early_blocks)
@@ -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);
@@ -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
@@ -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

Some files were not shown because too many files have changed in this diff Show More