feat(monero-sys): Build system (#500)

* feat: use contrib/depends to build dependencies

* fix: bump min iOS sdk to 13

* fix: macos targets

* fix: show make output during build
fix: mingw linking issues

* chore: address AI review

* check target only once, stream make output to stdout, init ios project

* check whether patch is already applied before trying again

* copy contrib/depends to target dir and build dependencies there

* fix: use proper triplet for ios-sim

* fix(dprint): ignore monero_c, monero and monero-seed folders

* fix(swap): Missing import

* fix(ci): Add gperf as a required dependency for Linux

* add notes for unsafe usage to CLAUDE.md

* add clean command to justfile

* fix: minimumSystemVersion to 11.0 because tauri doesn't default behavior is wild

* update crunchy dependency to fix linux->windows cross compilation issue

* fix last commit

* link c++ std lib and libgcc statically on windows

* embed WebView2 Bootstrapper

* disable ccache on ios, update tauri deps, set minimumSystemVersion to 13.0

* fix

* fix: build env leaking into contrib/depends

* fix: version '-sim' in target triple 'arm64-apple-ios13.0-simulator-sim' is invalid

* get it working on ios

* Upgrade to nightly Rust toolchain for unstable features

- Change from Rust 1.85 to nightly to support yamux unstable features
- This resolves the unsigned_is_multiple_of compilation error

* fix

* WINDOWS WORKS

* Cargo.lock update

* android progress

* progress on gcc build script

* remove windows binary dependencies from git, running just prepare-windows-build will re-create them

* check for .dll's in src-tauri/build.rs and give hint how to build them

* document new build requirement

* add verification to gcc build script and error message when building windows from os other than linux

* fix windows build

* add just command for building windows  ss

* fix script: remove sudo, copy dlls when finished

* move path setup to its own function

* fix

* try and fix ci

* extract setup to single action

* clean up ci

* add actions/checkout everywhere

* fix missing input prefix

* fix missing autoconf

* fix add build deps to env

* fix add build deps to env

* add deps for cross building windows

* fix action call

* only bundle dll's on windows

* use ubuntu-latest, install yarn, don't use swap

* add build dependencies, remove no longer existing docker test

* add aclocal to macos setup

* include macos build depends

* change platform -> host for setup-build-environment, use matrix for building binaries for all platforms

* fix: prepare build env for docker for ubuntu, don't get host value from matrix

* manually install rust target

* include openssl on ubuntu for sqlx

* build cargo cache once before building individual tests

* only manually install target if provided

* fix: don't need special syntax for variables in if condition

* fix libssl problem by upgrading sqlx cli

* fix: specify host for prepare_docker_tests

* a lot of fixes

---------

Co-authored-by: Czarek Nakamoto <cyjan@mrcyjanek.net>
Co-authored-by: einliterflasche <einliterflasche@pm.me>
Co-authored-by: binarybaron <you@example.com>
Co-authored-by: Raphael <81313171+Einliterflasche@users.noreply.github.com>
This commit is contained in:
Mohan 2025-08-27 16:45:59 +02:00 committed by GitHub
parent 41bc03f844
commit f2b23348d7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
113 changed files with 9245 additions and 11279 deletions

View file

@ -2,7 +2,40 @@
[target.armv7-unknown-linux-gnueabihf] [target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc" linker = "arm-linux-gnueabihf-gcc"
# Windows defaults to smaller stack sizes which isn't enough due to # Windows defaults to smaller stack sizes which isn't enough
# our ginormous call stacks # For the MSVC tool-chain
[target.'cfg(windows)'] [target.'cfg(all(windows, target_env = "msvc"))']
rustflags = ["-C", "link-args=/STACK:8388608"] rustflags = ["-C", "link-arg=/STACK:8388608"]
# For the GNU/MinGW tool-chain
[target.'cfg(all(windows, target_env = "gnu"))']
linker = "x86_64-w64-mingw32-g++" # Use g++ driver so -lstdc++ gets pulled in automatically
rustflags = [
"-C",
"link-arg=-Wl,--stack,8388608",
"-C",
"link-arg=-ladvapi32",
"-C",
"link-arg=-lrpcrt4",
"-C",
"link-arg=-lole32",
"-C",
"link-arg=-lwinhttp",
"-C",
"link-arg=-lcrypt32",
"-C",
"link-arg=-static-libgcc",
"-C", "link-arg=-static-libstdc++",
]
[target.aarch64-linux-android]
linker = "/home/me/Android/Sdk/ndk/27.3.13750724/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android24-clang"
ar = "/home/me/Android/Sdk/ndk/27.3.13750724/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-ar"
rustflags = [
"-Lnative=/home/me/Android/Sdk/ndk/27.3.13750724/toolchains/llvm/prebuilt/linux-x86_64/lib/clang/18/lib/linux",
"-lstatic=clang_rt.builtins-aarch64-android",
# "-Lnative=/home/me/Android/Sdk/ndk/27.3.13750724/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android",
# "-lstatic=c++abi",
]

View file

@ -1,9 +1,11 @@
--- ---
description: Don't run cargo commands. Ask the user to compile. description: Don't run cargo clean. Ask the user to confirm.
globs: globs:
alwaysApply: true alwaysApply: true
--- ---
Only run cargo commands after asking the user. Prefer not to run cargo commands. Ask the user to compile. Only run cargo clean after asking the user.
If the user says "run cargo commands" then use cargo commands. If the user says "run cargo clean" then use cargo clean.
The codebase takes a long ass time to compile, that's why.

View file

@ -1,27 +1,21 @@
name: 'Set Monero Environment Variables' name: "Set Monero Environment Variables"
description: 'Sets common environment variables for Monero dependencies across workflows' description: "Sets common environment variables for Monero dependencies across workflows"
runs: runs:
using: "composite" using: "composite"
steps: steps:
- name: Set environment variables - name: Set environment variables
shell: bash shell: bash
run: | run: |
# GUI-specific Ubuntu dependencies # GUI-specific Ubuntu dependencies
echo "DEPS_GUI_UBUNTU_SPECIFIC=libgtk-3-dev libappindicator3-dev librsvg2-dev libwebkit2gtk-4.1-0=2.44.0-2 libwebkit2gtk-4.1-dev=2.44.0-2 libjavascriptcoregtk-4.1-0=2.44.0-2 libjavascriptcoregtk-4.1-dev=2.44.0-2 gir1.2-javascriptcoregtk-4.1=2.44.0-2 gir1.2-webkit2-4.1=2.44.0-2" >> $GITHUB_ENV echo "DEPS_GUI_UBUNTU_SPECIFIC=libgtk-3-dev libappindicator3-dev librsvg2-dev libwebkit2gtk-4.1-0 libwebkit2gtk-4.1-dev libjavascriptcoregtk-4.1-0 libjavascriptcoregtk-4.1-dev gir1.2-javascriptcoregtk-4.1 gir1.2-webkit2-4.1" >> $GITHUB_ENV
# Tauri Linux dependencies # Build tooling (Linux)
echo "DEPS_TAURI_LINUX=libwebkit2gtk-4.1-dev curl wget file libxdo-dev libayatana-appindicator3-dev librsvg2-dev" >> $GITHUB_ENV echo "DEPS_BUILD_LINUX=autoconf nsis mingw-w64 build-essential pkg-config libtool ccache make cmake gcc g++ git curl lbzip2 gperf g++-mingw-w64-x86-64" >> $GITHUB_ENV
# Linux dependencies # Build tooling (macos)
echo "DEPS_MONERO_LINUX=libabsl-dev libnghttp2-dev libevent-dev libexpat1-dev build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler git" >> $GITHUB_ENV echo "DEPS_BUILD_MACOS=autoconf automake pkg-config libtool ccache make cmake gcc git curl lbzip2 gperf" >> $GITHUB_ENV
# macOS dependencies
echo "DEPS_MONERO_MACOS=cmake boost openssl zmq libpgm miniupnpc expat libunwind-headers protobuf" >> $GITHUB_ENV
# Windows MSYS2 dependencies
echo 'DEPS_MONERO_WINDOWS_MSYS2=mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-unbound git' >> $GITHUB_ENV
# APT configuration for better reliability # APT configuration for better reliability
echo 'APT_SET_CONF_COMMAND<<EOF echo 'APT_SET_CONF_COMMAND<<EOF
sudo tee -a /etc/apt/apt.conf.d/80-custom << APTEOF sudo tee -a /etc/apt/apt.conf.d/80-custom << APTEOF
@ -30,7 +24,7 @@ runs:
Acquire::ftp::Timeout "120"; Acquire::ftp::Timeout "120";
APTEOF APTEOF
EOF' >> $GITHUB_ENV EOF' >> $GITHUB_ENV
- name: Set platform identifiers - name: Set platform identifiers
shell: bash shell: bash
run: | run: |
@ -39,4 +33,4 @@ runs:
echo "UBUNTU_PLATFORM_ID=ubuntu-24.04" >> $GITHUB_ENV echo "UBUNTU_PLATFORM_ID=ubuntu-24.04" >> $GITHUB_ENV
echo "MACOS_INTEL=macos-13" >> $GITHUB_ENV echo "MACOS_INTEL=macos-13" >> $GITHUB_ENV
echo "WINDOWS=windows-latest" >> $GITHUB_ENV echo "WINDOWS=windows-latest" >> $GITHUB_ENV
echo "WINDOWS_PLATFORM_ID=windows-latest" >> $GITHUB_ENV echo "WINDOWS_PLATFORM_ID=windows-latest" >> $GITHUB_ENV

View file

@ -0,0 +1,107 @@
name: "Setup Build Environment"
description: "Sets up the build environment with Node, Rust, dependencies, and tooling for Tauri builds"
inputs:
host:
description: "The host being built on (e.g., ubuntu-24.04, macos-latest)"
required: true
target:
description: "Additional Rust targets to install and prepare for (e.g. x86_64-pc-windows-gnu when crossbuilding)"
required: false
default: "x86_64-unknown-linux-gnu"
runs:
using: "composite"
steps:
- name: Configure apt for retries (Ubuntu only)
if: startsWith(inputs.host, 'ubuntu')
shell: bash
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Set env variables
uses: ./.github/actions/set-monero-env
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Setup yarn
shell: bash
run: |
npm install --global yarn@1
- name: Install Rust stable
uses: dtolnay/rust-toolchain@1.87
with:
targets: ${{ inputs.target }}
- name: Install Tauri and build dependencies (Ubuntu)
if: contains(inputs.host, 'ubuntu')
shell: bash
run: |
sudo apt update;
sudo apt install -y ${{ env.DEPS_GUI_UBUNTU_SPECIFIC }} ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_BUILD_LINUX }} git
- name: Install build dependencies (macos)
if: contains(inputs.host, 'macos')
shell: bash
run: |
brew install ${{ env.DEPS_BUILD_MACOS }}
- name: Clone submodules
shell: bash
run: git submodule update --init --recursive
- name: Work around spurious network errors in curl 8.0
shell: bash
run: |
echo "CARGO_HTTP_MULTIPLEXING=false" >> $GITHUB_ENV
- name: Install frontend dependencies
working-directory: src-gui
shell: bash
run: yarn install --network-timeout 600000
- name: Install tauri-cli globally
uses: taiki-e/install-action@v2
with:
tool: tauri-cli@2.8.0
- name: Install just globally
uses: taiki-e/install-action@v2
with:
tool: just@1.42.4
- name: Install typeshare-cli globally
uses: taiki-e/install-action@v2
with:
tool: typeshare-cli@1.13.3
- name: Install dprint globally
uses: taiki-e/install-action@v2
with:
tool: dprint@0.50.1
- name: Install sqlx-cli globally
uses: taiki-e/install-action@v2
with:
tool: sqlx-cli@0.8.6
- name: Install cross (armv7)
if: inputs.host == 'armv7-unknown-linux-gnueabihf'
uses: taiki-e/install-action@v2
with:
tool: cross
- name: Make sure we really have the rust target installed
if: inputs.target != ''
shell: bash
run: |
rustup target add ${{ inputs.target }}
- name: Prepare Windows build by building gcc from source
if: contains(inputs.target, 'windows')
shell: bash
run: |
just prepare-windows-build

View file

@ -1,178 +0,0 @@
# This file is used to build the preview release binaries for the Tauri GUI with CloudNebula integration
name: "Publish GUI release to CloudNebula"
on:
release:
types: [created]
concurrency:
group: build-gui-release-cb-${{ github.event.release.tag_name }}
cancel-in-progress: true
env:
# We build on an older version to support older glib versions
UBUNTU: "ubuntu-24.04"
MACOS_ARM: "macos-latest"
MACOS_INTEL: "macos-13"
WINDOWS: "windows-latest"
CN_APPLICATION: "unstoppableswap/unstoppableswap-gui-rs"
DEPS_MONERO_LINUX: 'build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler git'
DEPS_GUI_UBUNTU_SPECIFIC: 'libgtk-3-dev libappindicator3-dev librsvg2-dev libwebkit2gtk-4.1-0=2.44.0-2 libwebkit2gtk-4.1-dev=2.44.0-2 libjavascriptcoregtk-4.1-0=2.44.0-2 libjavascriptcoregtk-4.1-dev=2.44.0-2 gir1.2-javascriptcoregtk-4.1=2.44.0-2 gir1.2-webkit2-4.1=2.44.0-2'
DEPS_MONERO_MACOS: 'cmake boost hidapi openssl zmq libpgm miniupnpc expat libunwind-headers protobuf'
DEPS_MONERO_WINDOWS_MSYS2: >-
mingw-w64-x86_64-toolchain
make
mingw-w64-x86_64-cmake
mingw-w64-x86_64-boost
mingw-w64-x86_64-openssl
mingw-w64-x86_64-zeromq
mingw-w64-x86_64-libsodium
mingw-w64-x86_64-hidapi
mingw-w64-x86_64-protobuf-c
mingw-w64-x86_64-libusb
mingw-w64-x86_64-unbound
git
APT_SET_CONF_COMMAND: |
sudo tee -a /etc/apt/apt.conf.d/80-custom << EOF
Acquire::Retries "3";
Acquire::http::Timeout "120";
Acquire::ftp::Timeout "120";
EOF
jobs:
draft-cb-release:
# Do not publish preview releases to CloudNebula
if: ${{ !contains(github.ref_name, 'preview') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create Draft Release
uses: crabnebula-dev/cloud-release@v0
with:
command: release draft ${{ env.CN_APPLICATION }} --framework tauri
api-key: ${{ secrets.CN_API_KEY }}
build:
needs: draft-cb-release
strategy:
fail-fast: false
matrix:
include:
- platform: "macos-latest" # For Arm-based Macs (M1 and above)
args: "--target aarch64-apple-darwin"
- platform: "macos-13" # For Intel-based Macs
args: "--target x86_64-apple-darwin"
- platform: "ubuntu-24.04"
args: ""
# Temporarily disabled Windows builds
# - platform: "windows-latest"
# args: ""
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 'lts/*'
- name: Install Rust Stable
uses: dtolnay/rust-toolchain@1.80
with:
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Configure apt for retries (ubuntu only)
if: matrix.platform == env.UBUNTU
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu only)
if: matrix.platform == env.UBUNTU # This must match the platform value defined above.
run: |
sudo apt update;
sudo apt install -y ${{ env.DEPS_MONERO_LINUX }} ${{ env.DEPS_GUI_UBUNTU_SPECIFIC }} git
- name: Install Monero build dependencies (macOS)
if: startsWith(matrix.platform, 'macos')
run: |
brew update
brew install python@3.13 || true
brew link --overwrite python@3.13
brew install ${{ env.DEPS_MONERO_MACOS }} git
brew reinstall --build-from-source unbound expat
brew install protobuf@21
- name: Install Monero build dependencies (Windows)
if: matrix.platform == env.WINDOWS
uses: msys2/setup-msys2@v2
with:
update: true
install: ${{ env.DEPS_MONERO_WINDOWS_MSYS2 }} git
- name: Clone submodules
run: git submodule update --init --recursive
- name: Work around spurious network errors in curl 8.0
shell: bash
run: |
echo "CARGO_HTTP_MULTIPLEXING=false" >> $GITHUB_ENV
- name: Install Frontend Dependencies
working-directory: src-gui
# Set the yarn network timeout to a high value to avoid spurious network errors
run: yarn install --network-timeout 600000
- name: install tauri-cli globally
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: tauri-cli@2.1.0
- name: install typeshare-cli globally
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: typeshare-cli
- name: install dprint globally
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: dprint@0.50.0
- name: Build Tauri App
env:
GITHUB_TOKEN: ${{ secrets.BOTTY_GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_SIGNING_IDENTITY: ${{ secrets.APPLE_SIGNING_IDENTITY }}
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
run: |
cargo tauri build ${{ matrix.args }}
- name: Upload Assets
uses: crabnebula-dev/cloud-release@v0
with:
command: release upload ${{ env.CN_APPLICATION }} --framework tauri
api-key: ${{ secrets.CN_API_KEY }}
publish:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: recursive
- uses: actionhippie/swap-space@v1
with:
size: 15G
- name: Publish Release
uses: crabnebula-dev/cloud-release@v0
with:
command: release publish ${{ env.CN_APPLICATION }} --framework tauri
api-key: ${{ secrets.CN_API_KEY }}

View file

@ -10,114 +10,47 @@ concurrency:
cancel-in-progress: true cancel-in-progress: true
jobs: jobs:
publish-tauri: draft-cb-release:
# Do not publish preview releases to Github. # Do not publish preview releases to CloudNebula
# Building takes too long for preview releases. if: ${{ !contains(github.ref_name, 'preview') }}
# if: ${{ !contains(github.ref_name, 'preview') }} Temporarily disabled runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create Draft Release
uses: crabnebula-dev/cloud-release@v0
with:
command: release draft ${{ env.CN_APPLICATION }} --framework tauri
api-key: ${{ secrets.CN_API_KEY }}
build:
permissions: permissions:
contents: write contents: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
include: include:
- platform: "macos-latest" # for Arm based macs (M1 and above). - host: "macos-latest" # for Arm based macs (M1 and above).
args: "--target aarch64-apple-darwin" target: "aarch64-apple-darwin"
- platform: "macos-13" # for Intel based macs. - host: "macos-13" # for Intel based macs.
args: "--target x86_64-apple-darwin" target: "x86_64-apple-darwin"
- platform: "ubuntu-24.04" # We build on an older version to support older glib versions - host: "ubuntu-22.04" # We build on an older version to support older glib versions
args: "--bundles deb,appimage" target: "x86_64-unknown-linux-gnu"
# Temporarily disabled Windows builds - host: "ubuntu-22.04" # cross build windows from ubuntu
# - platform: "windows-latest" target: "x86_64-pc-windows-gnu"
# args: ""
runs-on: ${{ matrix.platform }} runs-on: ${{ matrix.host }}
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
submodules: recursive host: ${{ matrix.host }}
target: ${{ matrix.target }}
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1 - name: build tauri app and upload to github releases page
if: matrix.platform == env.UBUNTU_PLATFORM_ID uses: tauri-apps/tauri-action@v0
with:
size: 15G
- name: setup node
uses: actions/setup-node@v4
with:
node-version: lts/*
- name: install Rust stable
uses: dtolnay/rust-toolchain@1.80
with:
# Those targets are only used on macos runners so it's in an `if` to slightly speed up windows and linux builds.
targets: ${{ matrix.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }}
- name: Configure apt for retries (ubuntu only)
if: matrix.platform == env.UBUNTU_PLATFORM_ID
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: install dependencies (ubuntu only)
if: matrix.platform == env.UBUNTU_PLATFORM_ID # This must match the platform value defined above.
run: |
sudo apt update;
sudo apt install -y ${{ env.DEPS_MONERO_LINUX }} ${{ env.DEPS_GUI_UBUNTU_SPECIFIC }} git
- name: Get OpenSSL location
if: matrix.platform == env.UBUNTU_PLATFORM_ID
run: |
which openssl
openssl version
echo "OPENSSL_PATH=$(which openssl)" >> $GITHUB_ENV
- name: Install Monero build dependencies (macOS)
if: startsWith(matrix.platform, 'macos')
run: |
brew update
brew install python@3.13 || true
brew link --overwrite python@3.13
brew install ${{ env.DEPS_MONERO_MACOS }} git
brew reinstall --build-from-source unbound expat
brew install protobuf@21
- name: Install Monero build dependencies (Windows)
if: matrix.platform == env.WINDOWS_PLATFORM_ID
uses: msys2/setup-msys2@v2
with:
update: true
install: ${{ env.DEPS_MONERO_WINDOWS_MSYS2 }} git
- name: Clone submodules
run: git submodule update --init --recursive
- name: work around spurious network errors in curl 8.0
shell: bash
run: |
echo "CARGO_HTTP_MULTIPLEXING=false" >> $GITHUB_ENV
- name: install frontend dependencies
working-directory: src-gui
# Set the yarn network timeout to a high value to avoid spurious network errors
run: yarn install --network-timeout 600000
- name: install tauri-cli globally
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: tauri-cli@2.1.0
- name: install typeshare-cli globally
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: typeshare-cli
- name: install dprint globally
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: dprint@0.50.0
- uses: tauri-apps/tauri-action@v0
env: env:
GITHUB_TOKEN: ${{ secrets.BOTTY_GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.BOTTY_GITHUB_TOKEN }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }} APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
@ -127,9 +60,29 @@ jobs:
APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }} APPLE_PASSWORD: ${{ secrets.APPLE_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }} TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }} TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD }}
with: with:
releaseId: ${{ github.event.release.id }} releaseId: ${{ github.event.release.id }}
projectPath: src-tauri projectPath: src-tauri
args: ${{ matrix.args }} tauriScript: cargo tauri
tauriScript: cargo tauri
- name: upload to crabnebula release (not for previews)
if: ${{ !contains(github.ref_name, 'preview') }}
uses: crabnebula-dev/cloud-release@v0
with:
command: release upload ${{ env.CN_APPLICATION }} --framework tauri
api-key: ${{ secrets.CN_API_KEY }}
args: --target ${{ matrix.target }}
publish:
if: ${{ !contains(github.ref_name, 'preview') }} # don't publish previews to crabnebula
needs: [draft-cb-release, build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Publish Release
uses: crabnebula-dev/cloud-release@v0
with:
command: release publish ${{ env.CN_APPLICATION }} --framework tauri
api-key: ${{ secrets.CN_API_KEY }}

View file

@ -17,199 +17,43 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
bin: [swap, asb, asb-controller, orchestrator]
target:
[
x86_64-unknown-linux-gnu,
aarch64-apple-darwin,
x86_64-apple-darwin,
x86_64-pc-windows-gnu,
]
host: [ubuntu-22.04] # default host: ubuntu
archive_extension: [tar] # default extension: tar
include: include:
- bin: swap # build for arm macos on arm macos
crate: swap - target: aarch64-apple-darwin
target: x86_64-unknown-linux-gnu host: macos-latest
os: ubuntu-latest # build for intel macos on intel macos
archive_ext: tar - target: x86_64-apple-darwin
# Temporarily disabled armv7 Linux builds host: macos-13
# - bin: swap # use .zip for windows
# crate: swap - target: x86_64-pc-windows-gnu
# target: armv7-unknown-linux-gnueabihf archive_extension: zip
# os: ubuntu-latest
# archive_ext: tar runs-on: ${{ matrix.host }}
- bin: swap
crate: swap
target: x86_64-apple-darwin
os: macos-13
archive_ext: tar
- bin: swap
crate: swap
target: aarch64-apple-darwin
os: macos-latest
archive_ext: tar
# Temporarily disabled Windows builds
# - bin: swap
# crate: swap
# target: x86_64-pc-windows-msvc
# os: windows-latest
# archive_ext: zip
- bin: asb
crate: swap-asb
target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive_ext: tar
# Temporarily disabled armv7 Linux builds
# - bin: asb
# crate: swap-asb
# target: armv7-unknown-linux-gnueabihf
# os: ubuntu-latest
# archive_ext: tar
- bin: asb
crate: swap-asb
target: x86_64-apple-darwin
os: macos-13
archive_ext: tar
- bin: asb
crate: swap-asb
target: aarch64-apple-darwin
os: macos-latest
archive_ext: tar
# Temporarily disabled Windows builds
# - bin: asb
# crate: swap-asb
# target: x86_64-pc-windows-msvc
# os: windows-latest
# archive_ext: zip
- bin: asb-controller
crate: swap-controller
target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive_ext: tar
# Temporarily disabled armv7 Linux builds
# - bin: asb-controller
# crate: swap-controller
# target: armv7-unknown-linux-gnueabihf
# os: ubuntu-latest
# archive_ext: tar
- bin: asb-controller
crate: swap-controller
target: x86_64-apple-darwin
os: macos-13
archive_ext: tar
- bin: asb-controller
crate: swap-controller
target: aarch64-apple-darwin
os: macos-latest
archive_ext: tar
# Temporarily disabled Windows builds
# - bin: asb-controller
# crate: swap-controller
# target: x86_64-pc-windows-msvc
# os: windows-latest
# archive_ext: zip
- bin: orchestrator
crate: swap-orchestrator
target: x86_64-unknown-linux-gnu
os: ubuntu-latest
archive_ext: tar
# Temporarily disabled armv7 Linux builds
# - bin: orchestrator
# crate: swap-orchestrator
# target: armv7-unknown-linux-gnueabihf
# os: ubuntu-latest
# archive_ext: tar
- bin: orchestrator
crate: swap-orchestrator
target: x86_64-apple-darwin
os: macos-13
archive_ext: tar
- bin: orchestrator
crate: swap-orchestrator
target: aarch64-apple-darwin
os: macos-latest
archive_ext: tar
# Temporarily disabled Windows builds
# - bin: orchestrator
# crate: swap-orchestrator
# target: x86_64-pc-windows-msvc
# os: windows-latest
# archive_ext: zip
runs-on: ${{ matrix.os }}
steps: steps:
- name: Checkout tagged commit - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7
- name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
ref: ${{ github.event.release.target_commitish }} host: ${{ matrix.host }}
token: ${{ secrets.BOTTY_GITHUB_TOKEN }} target: ${{ matrix.target }}
submodules: recursive
- name: Set up environment variables - name: Build ${{ matrix.bin }} in release mode
uses: ./.github/actions/set-monero-env run: cargo build --bin ${{ matrix.bin }} --release -vv
- uses: actionhippie/swap-space@v1
if: matrix.os == 'ubuntu-latest'
with:
size: 15G
- name: Restore Rust/Cargo cache from S3
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
- name: Install Rust toolchain (no internal cache)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""
cache-directories: ""
- name: Configure apt for retries
if: matrix.os == 'ubuntu-latest'
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest)
if: matrix.os == 'ubuntu-latest'
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }} git
- name: Clone submodules
run: git submodule update --init --recursive
- name: Install Monero build dependencies (macOS)
if: startsWith(matrix.os, 'macos')
run: |
brew update
brew install ${{ env.DEPS_MONERO_MACOS }} git
brew reinstall --build-from-source unbound expat
brew install protobuf@21
- name: Install Monero build dependencies (Windows)
if: matrix.os == 'windows-latest'
uses: msys2/setup-msys2@v2
with:
update: true
install: ${{ env.DEPS_MONERO_WINDOWS_MSYS2 }} git
- name: Clone submodules
run: git submodule update --init --recursive
- name: Cross Build ${{ matrix.target }} ${{ matrix.bin }} binary
if: matrix.target == 'armv7-unknown-linux-gnueabihf'
run: |
curl -L "https://github.com/cross-rs/cross/releases/download/v0.2.5/cross-x86_64-unknown-linux-gnu.tar.gz" | tar xzv
sudo mv cross /usr/bin
sudo mv cross-util /usr/bin
cross build --target=${{ matrix.target }} --release --package ${{ matrix.crate }} --bin ${{ matrix.bin }}
- name: Build ${{ matrix.target }} ${{ matrix.bin }} release binary
if: matrix.target != 'armv7-unknown-linux-gnueabihf'
run: cargo build --target=${{ matrix.target }} --release --package ${{ matrix.crate }} --bin ${{ matrix.bin }}
- name: Smoke test the binary - name: Smoke test the binary
if: matrix.target != 'armv7-unknown-linux-gnueabihf' && matrix.bin != 'orchestrator' if: matrix.bin != 'orchestrator' # ignore orchestrator, since it's interactive
run: target/${{ matrix.target }}/release/${{ matrix.bin }} --help run: target/${{ matrix.target }}/release/${{ matrix.bin }} --help
- id: create-archive-name - id: create-archive-name
@ -223,22 +67,22 @@ jobs:
triple = "${{ matrix.target }}".split("-") triple = "${{ matrix.target }}".split("-")
arch = triple[0] arch = triple[0]
archive_name=f'${{ matrix.bin }}_${{ github.event.release.tag_name }}_{os_info.system}_{arch}.${{ matrix.archive_ext }}' archive_name=f'${{ matrix.bin }}_${{ github.event.release.tag_name }}_{os_info.system}_{arch}.${{ matrix.archive_extension }}'
print(f'::set-output name=archive::{archive_name}') print(f'::set-output name=archive::{archive_name}')
- name: Pack macos archive - name: Pack macos archive
if: startsWith(matrix.os, 'macos') if: contains(matrix.target, 'apple')
shell: bash shell: bash
run: gtar -C ./target/${{ matrix.target }}/release --create --file=${{ steps.create-archive-name.outputs.archive }} ${{ matrix.bin }} run: gtar -C ./target/${{ matrix.target }}/release --create --file=${{ steps.create-archive-name.outputs.archive }} ${{ matrix.bin }}
- name: Pack linux archive - name: Pack linux archive
if: matrix.os == 'ubuntu-latest' if: contains(matrix.target, 'linux')
shell: bash shell: bash
run: tar -C ./target/${{ matrix.target }}/release --create --file=${{ steps.create-archive-name.outputs.archive }} ${{ matrix.bin }} run: tar -C ./target/${{ matrix.target }}/release --create --file=${{ steps.create-archive-name.outputs.archive }} ${{ matrix.bin }}
- name: Pack windows archive - name: Pack windows archive
if: matrix.os == 'windows-latest' if: contains(matrix.target, 'windows')
shell: bash shell: bash
run: | run: |
cp target/${{ matrix.target }}/release/${{ matrix.bin }}.exe ./${{ matrix.bin }}.exe cp target/${{ matrix.target }}/release/${{ matrix.bin }}.exe ./${{ matrix.bin }}.exe
@ -254,23 +98,6 @@ jobs:
asset_name: ${{ steps.create-archive-name.outputs.archive }} asset_name: ${{ steps.create-archive-name.outputs.archive }}
asset_content_type: application/gzip asset_content_type: application/gzip
- name: Save Rust/Cargo cache to S3
if: ${{ always() }}
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
build_and_push_docker: build_and_push_docker:
name: Build and Push Docker Image name: Build and Push Docker Image
runs-on: ubuntu-latest runs-on: ubuntu-latest
@ -279,26 +106,12 @@ jobs:
contents: read contents: read
packages: write packages: write
steps: steps:
- name: Checkout code - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7
- name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
ref: ${{ github.event.release.target_commitish }} host: ubuntu-latest
submodules: recursive
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1
with:
size: 15G
- name: Configure apt for retries
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest)
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2 uses: docker/setup-buildx-action@v2
@ -357,4 +170,4 @@ jobs:
file: ./swap-controller/Dockerfile file: ./swap-controller/Dockerfile
push: true push: true
tags: ${{ env.DOCKER_IMAGE_NAME }}:${{ github.event.release.tag_name }} tags: ${{ env.DOCKER_IMAGE_NAME }}:${{ github.event.release.tag_name }}
if: steps.docker_tags.outputs.preview == 'true' if: steps.docker_tags.outputs.preview == 'true'

View file

@ -12,59 +12,15 @@ concurrency:
jobs: jobs:
static_analysis: static_analysis:
runs-on: ubuntu-latest-m runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft if: github.event_name == 'push' || !github.event.pull_request.draft
steps: steps:
- name: Checkout sources - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7
- name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
submodules: recursive host: ubuntu-latest
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1
with:
size: 15G
- name: Restore Rust/Cargo cache from S3
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
- name: Install Rust toolchain (no internal cache)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: clippy,rustfmt
rustflags: ""
cache-directories: ""
- name: Configure apt for retries
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest-m)
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }} git
- name: Clone submodules
run: git submodule update --init --recursive
- name: Check formatting
uses: dprint/check@v2.2
with:
dprint-version: 0.50.0
- name: Run clippy with default features - name: Run clippy with default features
run: cargo clippy --workspace --all-targets -- -D warnings run: cargo clippy --workspace --all-targets -- -D warnings
@ -72,55 +28,19 @@ jobs:
- name: Run clippy with all features enabled - name: Run clippy with all features enabled
run: cargo clippy --workspace --all-targets --all-features -- -D warnings run: cargo clippy --workspace --all-targets --all-features -- -D warnings
- name: Save Rust/Cargo cache to S3 sqlx_test:
if: ${{ always() }} runs-on: ubuntu-latest
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
bdk_test:
runs-on: ubuntu-latest-m
if: github.event_name == 'push' || !github.event.pull_request.draft if: github.event_name == 'push' || !github.event.pull_request.draft
steps: steps:
- name: Checkout sources - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7 - name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
submodules: recursive host: ubuntu-latest
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1 - name: Run sqlx cache setup script
with:
size: 15G
- name: Configure apt for retries
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest-m)
run: | run: |
sudo apt update just generate-sqlx-cache
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }}
- name: Clone submodules
run: git submodule update --init --recursive
- name: Build swap
run: cargo build --bin swap
- name: Run BDK regression script
run: ./swap/tests/bdk.sh
build: build:
strategy: strategy:
@ -128,95 +48,27 @@ jobs:
matrix: matrix:
include: include:
- target: x86_64-unknown-linux-gnu - target: x86_64-unknown-linux-gnu
os: ubuntu-latest-m os: ubuntu-latest
# Temporarily disabled armv7 Linux builds
# - target: armv7-unknown-linux-gnueabihf
# os: ubuntu-latest-m
- target: x86_64-apple-darwin - target: x86_64-apple-darwin
os: macos-13 os: macos-13
- target: aarch64-apple-darwin - target: aarch64-apple-darwin
os: macos-latest os: macos-latest
# Temporarily disabled Windows builds - target: x86_64-pc-windows-gnu
# - target: x86_64-pc-windows-msvc os: ubuntu-latest
# os: windows-latest-l
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || !github.event.pull_request.draft if: github.event_name == 'push' || !github.event.pull_request.draft
steps: steps:
- name: Checkout sources - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7 - name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
submodules: recursive host: ${{ matrix.os }}
target: ${{ matrix.target }}
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1
if: matrix.os == 'ubuntu-latest-m'
with:
size: 15G
- name: Restore Rust/Cargo cache from S3
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
- name: Install Rust toolchain (no internal cache)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""
cache-directories: ""
- name: Configure apt for retries
if: matrix.os == 'ubuntu-latest-m'
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest-m)
if: matrix.os == 'ubuntu-latest-m' # This must match the platform value defined above.
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }} git
- name: Clone submodules
run: git submodule update --init --recursive
- name: Install Monero build dependencies (macOS)
if: startsWith(matrix.os, 'macos-')
run: |
brew update
brew install ${{ env.DEPS_MONERO_MACOS }}
brew reinstall --build-from-source unbound expat
brew install protobuf@21
- name: Install Monero build dependencies (Windows)
if: matrix.os == 'windows-latest-l'
uses: msys2/setup-msys2@v2
with:
update: true
install: ${{ env.DEPS_MONERO_WINDOWS_MSYS2 }}
- name: Build binary - name: Build binary
if: matrix.target != 'armv7-unknown-linux-gnueabihf'
run: cargo build -p swap --target ${{ matrix.target }} run: cargo build -p swap --target ${{ matrix.target }}
- name: Install cross (armv7)
if: matrix.target == 'armv7-unknown-linux-gnueabihf'
run: cargo install cross --locked
- name: Build binary (armv7)
if: matrix.target == 'armv7-unknown-linux-gnueabihf'
run: cross build -p swap --target ${{ matrix.target }}
- name: Upload swap binary - name: Upload swap binary
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
@ -229,128 +81,49 @@ jobs:
name: asb-${{ matrix.target }} name: asb-${{ matrix.target }}
path: target/${{ matrix.target }}/debug/asb path: target/${{ matrix.target }}/debug/asb
- name: Save Rust/Cargo cache to S3
if: ${{ always() }}
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-${{ matrix.target }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
test: test:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
os: [ubuntu-latest-m, macos-latest] os: [ubuntu-latest, macos-latest]
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
if: github.event_name == 'push' || !github.event.pull_request.draft if: github.event_name == 'push' || !github.event.pull_request.draft
steps: steps:
- name: (Free disk space on Ubuntu) - uses: actions/checkout@v4
if: matrix.os == 'ubuntu-latest-m' - name: Setup build environment (cli tools, dependencies)
uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be uses: ./.github/actions/setup-build-environment
with: with:
# removing all of these takes ~10 mins, so just do as needed host: ${{ matrix.os }}
android: true
dotnet: true
haskell: true
docker-images: false
large-packages: false
swap-storage: false
tool-cache: false
- name: Checkout sources
uses: actions/checkout@v4.1.7
with:
submodules: recursive
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1
if: matrix.os == 'ubuntu-latest-m'
with:
size: 15G
- name: Restore Rust/Cargo cache from S3
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
- name: Install Rust toolchain (no internal cache)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""
cache-directories: ""
- name: Configure apt for retries
if: matrix.os == 'ubuntu-latest-m'
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest-m)
if: matrix.os == 'ubuntu-latest-m'
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }}
- name: Install Monero build dependencies (macOS)
if: matrix.os == 'macos-latest'
run: |
brew update
brew install ${{ env.DEPS_MONERO_MACOS }}
brew reinstall --build-from-source unbound expat
brew install protobuf@21
- name: Clone submodules
run: git submodule update --init --recursive
- name: Build tests
run: cargo build --tests --workspace --all-features
- name: Run monero-harness tests - name: Run monero-harness tests
if: matrix.os == 'ubuntu-latest-m' if: matrix.os == 'ubuntu-latest'
run: cargo test --package monero-harness --all-features run: cargo test --package monero-harness --all-features
- name: Run library tests for swap - name: Run library tests for swap
run: cargo test --package swap --lib run: cargo test --package swap --lib
- name: Save Rust/Cargo cache to S3 prepare_docker_tests:
if: ${{ always() }} runs-on: ubuntu-22.04
uses: whywaita/actions-cache-s3@v2 if: github.event_name == 'push' || !github.event.pull_request.draft
steps:
- uses: actions/checkout@v4
- name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
path: | host: ubuntu-22.04
~/.rustup
~/.cargo/registry - name: Run cargo build once to build the cache
~/.cargo/git run: cargo build --package swap
target
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }} - name: Cache target directory
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }} uses: actions/cache/save@v4
aws-region: eu-central-1 with:
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }} path: target/
aws-s3-force-path-style: true key: cargo-build-${{ github.sha }}
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
docker_tests: docker_tests:
needs: prepare_docker_tests
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
@ -393,102 +166,35 @@ jobs:
test_name: alice_empty_balance_after_started_btc_early_refund test_name: alice_empty_balance_after_started_btc_early_refund
- package: swap - package: swap
test_name: alice_broken_wallet_rpc_after_started_btc_early_refund test_name: alice_broken_wallet_rpc_after_started_btc_early_refund
- package: monero-sys
test_name: harness_test runs-on: ubuntu-latest
runs-on: ubuntu-latest-m
if: github.event_name == 'push' || !github.event.pull_request.draft if: github.event_name == 'push' || !github.event.pull_request.draft
steps: steps:
- name: Checkout sources - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7
- name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
submodules: recursive host: ubuntu-22.04
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1 - name: Restore build cache from perpare_docker_tests
uses: actions/cache/restore@v4
with: with:
size: 15G path: target/
key: cargo-build-${{ github.sha }}
- name: Configure apt for retries
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest-m)
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }}
- name: Clone submodules
run: git submodule update --init --recursive
- name: Run test ${{ matrix.test_name }} - name: Run test ${{ matrix.test_name }}
run: cargo test --package ${{ matrix.package }} --test ${{ matrix.test_name }} -- --nocapture run: cargo test --package ${{ matrix.package }} --test ${{ matrix.test_name }} -- --nocapture
check_stable: check_stable:
runs-on: ubuntu-latest-m runs-on: ubuntu-latest
if: github.event_name == 'push' || !github.event.pull_request.draft if: github.event_name == 'push' || !github.event.pull_request.draft
steps: steps:
- name: Checkout sources - uses: actions/checkout@v4
uses: actions/checkout@v4.1.7 - name: Setup build environment (cli tools, dependencies)
uses: ./.github/actions/setup-build-environment
with: with:
submodules: recursive host: ubuntu-latest
- name: Set up environment variables
uses: ./.github/actions/set-monero-env
- uses: actionhippie/swap-space@v1
with:
size: 15G
- name: Restore Rust/Cargo cache from S3
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}
- name: Install Rust toolchain (no internal cache)
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ""
cache-directories: ""
- name: Configure apt for retries
run: ${{ env.APT_SET_CONF_COMMAND }}
- name: Install dependencies (ubuntu-latest-m)
run: |
sudo apt update
sudo apt install -y ${{ env.DEPS_TAURI_LINUX }} ${{ env.DEPS_MONERO_LINUX }}
- name: Clone submodules
run: git submodule update --init --recursive
- name: Run cargo check on stable rust - name: Run cargo check on stable rust
run: cargo check --all-targets run: cargo check --all-targets
- name: Save Rust/Cargo cache to S3
if: ${{ always() }}
uses: whywaita/actions-cache-s3@v2
with:
path: |
~/.rustup
~/.cargo/registry
~/.cargo/git
target
key: ${{ runner.os }}-rust-${{ hashFiles('**/Cargo.lock') }}
aws-s3-bucket: ${{ secrets.S3_BUCKET_NAME }}
aws-region: eu-central-1
aws-endpoint: ${{ secrets.S3_ENDPOINT_URL }}
aws-s3-force-path-style: true
aws-access-key-id: ${{ secrets.S3_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.S3_SECRET_ACCESS_KEY }}

8
.gitmodules vendored
View file

@ -1,4 +1,8 @@
[submodule "monero-sys/monero"] [submodule "monero-sys/monero"]
path = monero-sys/monero path = monero-sys/monero
url = https://github.com/SNeedlewoods/seraphis_wallet.git url = https://github.com/mrcyjanek/monero
branch = x_api_add_new_functions_release branch = cyjan-fix-ios
[submodule "monero-sys/monero_c"]
path = monero-sys/monero_c
url = https://github.com/mrcyjanek/monero_c.git
branch = develop

4846
Cargo.lock generated

File diff suppressed because it is too large Load diff

View file

@ -65,11 +65,19 @@ dialoguer = "0.11"
# Build dependencies # Build dependencies
vergen = { version = "8.3", default-features = false, features = ["build", "git", "git2"] } vergen = { version = "8.3", default-features = false, features = ["build", "git", "git2"] }
vergen-git2 = { version = "1", features = ["build"] }
[patch.crates-io] [patch.crates-io]
# patch until new release https://github.com/thomaseizinger/rust-jsonrpc-client/pull/51 # patch until new release https://github.com/thomaseizinger/rust-jsonrpc-client/pull/51
jsonrpc_client = { git = "https://github.com/delta1/rust-jsonrpc-client.git", rev = "3b6081697cd616c952acb9c2f02d546357d35506" } jsonrpc_client = { git = "https://github.com/delta1/rust-jsonrpc-client.git", rev = "3b6081697cd616c952acb9c2f02d546357d35506" }
monero = { git = "https://github.com/comit-network/monero-rs", rev = "818f38b" } monero = { git = "https://github.com/comit-network/monero-rs", rev = "818f38b" }
# Force up to date version of crunchy that fixes linux->windows cross compilation
crunchy = { git = "https://github.com/eira-fransham/crunchy", rev = "ba7b86cea6ba89ccfc72ccb24cc4a4ac6d9c6272" }
[workspace.lints] [workspace.lints]
rust.unused_crate_dependencies = "warn" rust.unused_crate_dependencies = "warn"
[profile.release]
codegen-units = 1
lto = "fat"

View file

@ -0,0 +1,407 @@
#!/bin/bash
# Script to build gcc cross compiler for windows from source on ubuntu.
# Installed into ~/opt/gcc-mingw-14.3
# Versions
BINUTILS_VER=2.42
MINGW_VER=v12.0.0
GCC_VER=14.3.0
# Some flags for running only certain parts of the script.
# Set these to 1 before running the script to make use of them.
ONLY_WINPTHREADS="${ONLY_WINPTHREADS:-}"
ONLY_COPY_DLLS="${ONLY_COPY_DLLS:-}"
ONLY_VERIFY="${ONLY_VERIFY:-}"
# OS Detection and validation
detected=$(uname -s)-$(uname -m)
case "$detected" in
Linux-x86_64)
# Check if it's Ubuntu
if [ -f /etc/os-release ]; then
. /etc/os-release
if [ "$ID" != "ubuntu" ]; then
echo "This script is designed for ubuntu (x86-64) and doesn't support: ${detected} (${PRETTY_NAME})"
exit 1
fi
else
echo "This script is designed for ubuntu (x86-64) and doesn't support: ${detected}"
exit 1
fi
;;
*)
echo "This script is designed for ubuntu (x86-64) and doesn't support: ${detected}"
exit 1
;;
esac
set -euo pipefail
# Get the current project root (this file is in <root>/dev_scripts/ and gets called via just (just file is at <root>/justfile))
SRC_TAURI_DIR="$(pwd)/../src-tauri"
# Check if src-tauri directory exists
if [ ! -d "$SRC_TAURI_DIR" ]; then
echo "Error: must be called from project root -> src-tauri must be subdir"
echo "Current directory: $(pwd)"
exit 1
fi
install_deps() {
# Package installation (idempotent)
echo "Ensuring required packages are installed"
to_install=()
for pkg in gpg build-essential wget flex bison texinfo libgmp-dev libmpfr-dev libmpc-dev libisl-dev zlib1g-dev libbz2-dev libffi-dev python3 gnupg dirmngr ca-certificates jq; do
if ! dpkg -s "$pkg" >/dev/null 2>&1; then
echo "missing package: $pkg"
to_install+=("$pkg")
fi
done
if [ ${#to_install[@]} -gt 0 ]; then
sudo apt update
sudo apt install -y "${to_install[@]}"
else
echo "All required packages already installed"
fi
}
export PREFIX=~/opt/gcc-mingw-14.3
export BUILD=$HOME/mingw-build
export SRC=$BUILD/src
mkdir -p $SRC \
$BUILD/build-binutils \
$BUILD/build-headers \
$BUILD/build-gcc \
$BUILD/build-crt \
$BUILD/build-winpthreads \
$PREFIX
cd $SRC
download_if_missing() {
local url="$1"
local out="${2:-}"
local dest
if [ -n "$out" ]; then
dest="$out"
else
dest="$(basename "$url")"
fi
if [ -f "$dest" ]; then
echo "Already present: $dest"
else
echo "Downloading: $url"
wget -q "$url" -O "$dest"
fi
}
fetch_gpg_key() {
# Usage: fetch_gpg_key <keyid_or_fingerprint>
local key="$1"
# Try multiple hkps keyservers first
for ks in hkps://keyserver.ubuntu.com hkps://keys.openpgp.org hkps://pgp.mit.edu; do
if gpg --keyserver "$ks" --keyserver-options timeout=10 --recv-keys "$key"; then
return 0
fi
done
# HTTP fallback: Ubuntu keyserver
if ! gpg --list-keys "$key" >/dev/null 2>&1; then
if curl -fsSL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x${key}" | gpg --import; then
if gpg --list-keys "$key" >/dev/null 2>&1; then
return 0
fi
fi
fi
# HTTP fallback: keys.openpgp.org by fingerprint (no 0x)
if ! gpg --list-keys "$key" >/dev/null 2>&1; then
local fpr_no0x
fpr_no0x=$(echo "$key" | sed 's/^0x//')
curl -fsSL "https://keys.openpgp.org/vks/v1/by-fingerprint/${fpr_no0x}" | gpg --import || true
if gpg --list-keys "$key" >/dev/null 2>&1; then
return 0
fi
fi
return 1
}
ensure_key_and_verify() {
# Usage: ensure_key_and_verify <artifact> <signature>
local artifact="$1"
local sig="$2"
echo "Verifying signature: $sig for $artifact"
# First attempt: verify with whatever keys are available
if gpg --batch --status-fd 1 --verify "$sig" "$artifact" 2>verify.stderr | tee verify.status | grep -q "\[GNUPG:\] VALIDSIG"; then
echo "GPG verification OK for $artifact"
rm -f verify.status verify.stderr
return 0
fi
# If missing key, try to fetch by fingerprint or keyid
local missing_key
missing_key=$(grep "\[GNUPG:\] NO_PUBKEY" verify.status | awk '{print $3}' || true)
if [ -z "$missing_key" ]; then
# Try to extract key id from stderr (older gpg formats)
missing_key=$(grep -Eo 'key [0-9A-Fa-f]+' verify.stderr | awk '{print $2}' | tail -n1 || true)
fi
if [ -n "$missing_key" ]; then
echo "Missing public key: $missing_key. Attempting key fetch."
fetch_gpg_key "$missing_key" || true
fi
# Second attempt: verify again
if gpg --batch --status-fd 1 --verify "$sig" "$artifact" 2>/dev/null | grep -q "\[GNUPG:\] VALIDSIG"; then
echo "GPG verification OK for $artifact"
rm -f verify.status verify.stderr
return 0
fi
echo "ERROR: GPG verification failed for $artifact" >&2
echo "GPG status:"
cat verify.status || true
echo "GPG stderr:"
cat verify.stderr || true
rm -f verify.status verify.stderr
exit 1
}
download_sources() {
# Binutils
download_if_missing "https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VER}.tar.xz"
download_if_missing "https://ftp.gnu.org/gnu/binutils/binutils-${BINUTILS_VER}.tar.xz.sig"
ensure_key_and_verify "binutils-${BINUTILS_VER}.tar.xz" "binutils-${BINUTILS_VER}.tar.xz.sig"
tar xf "binutils-${BINUTILS_VER}.tar.xz"
# mingw-w64 headers & CRT
download_if_missing "https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/mingw-w64-${MINGW_VER}.tar.bz2"
download_if_missing "https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/mingw-w64-${MINGW_VER}.tar.bz2.sig"
ensure_key_and_verify "mingw-w64-${MINGW_VER}.tar.bz2" "mingw-w64-${MINGW_VER}.tar.bz2.sig"
tar xf "mingw-w64-${MINGW_VER}.tar.bz2"
# GCC
download_if_missing "https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/gcc-${GCC_VER}.tar.xz"
download_if_missing "https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/gcc-${GCC_VER}.tar.xz.sig"
ensure_key_and_verify "gcc-${GCC_VER}.tar.xz" "gcc-${GCC_VER}.tar.xz.sig"
tar xf "gcc-${GCC_VER}.tar.xz"
}
build_binutils() {
echo "Building binutils"
cd $BUILD/build-binutils
$SRC/binutils-${BINUTILS_VER}/configure \
--target=x86_64-w64-mingw32 \
--prefix=$PREFIX \
--with-sysroot=$PREFIX \
--disable-multilib
make -j$(nproc)
make install
export PATH="$PREFIX/bin:$PATH"
echo "Built binutils"
}
build_mingw_headers() {
echo "Building mingw-w64 headers"
cd $BUILD/build-headers
$SRC/mingw-w64-${MINGW_VER}/mingw-w64-headers/configure \
--host=x86_64-w64-mingw32 \
--prefix=$PREFIX/x86_64-w64-mingw32
make -j$(nproc)
make install
# fixes a path mismatch issue
if [ ! -L "$PREFIX/mingw" ]; then
ln -s $PREFIX/x86_64-w64-mingw32 $PREFIX/mingw
fi
echo "Built mingw-w64 headers"
}
prepare_gcc_build() {
echo "Building gcc"
cd $BUILD/build-gcc
$SRC/gcc-${GCC_VER}/configure \
--target=x86_64-w64-mingw32 \
--prefix=$PREFIX \
--with-sysroot=$PREFIX \
--disable-multilib \
--enable-languages=c,c++
make all-gcc -j$(nproc)
make install-gcc
echo "Built gcc"
}
build_mingw_crt() {
echo "Building mingw-w64 CRT"
cd $BUILD/build-crt
$SRC/mingw-w64-${MINGW_VER}/mingw-w64-crt/configure \
--host=x86_64-w64-mingw32 \
--prefix=$PREFIX/x86_64-w64-mingw32 \
--with-sysroot=$PREFIX
make -j$(nproc)
make install
echo "Built mingw-w64 CRT"
}
finish_gcc() {
echo "Finishing gcc build"
cd $BUILD/build-gcc
make -j$(nproc)
make install
echo "Built gcc"
}
build_winpthreads() {
echo "Building winpthreads.dll"
cd $BUILD/build-winpthreads
# 2. Configure winpthreads (static & shared)
$SRC/mingw-w64-${MINGW_VER}/mingw-w64-libraries/winpthreads/configure \
--host=x86_64-w64-mingw32 \
--prefix=$PREFIX/x86_64-w64-mingw32 \
--enable-static --enable-shared \
--disable-multilib
# 3. Build & install
make -j$(nproc)
make install
echo "Built winpthreads.dll"
}
copy_dlls() {
echo "Copying dll's to src-tauri/"
cp -f $PREFIX/x86_64-w64-mingw32/lib/{libstdc++-6,libgcc_s_seh-1}.dll $SRC_TAURI_DIR/
}
setup_path() {
# Add to PATH only if not already present
if [[ ":$PATH:" != *":$PREFIX/bin:"* ]]; then
export PATH="$PREFIX/bin:$PATH"
fi
# add path to bashrc
if ! grep -q "export PATH=\"$PREFIX/bin:\$PATH\"" ~/.bashrc; then
echo "export PATH=\"$PREFIX/bin:\$PATH\"" >> ~/.bashrc
fi
}
verify_installation() {
# 1. check that ~/opt/gcc-mingw-14.3/ exists
# 2. check that `x86_64-w64-mingw32-g++ --version` works and the output contains 14.3
# 3. make sure the dll's are in the src-tauri directory
echo "Verifying cross-compiler installation"
local has_error=0
# Ensure PREFIX dir exists
if [ ! -d "$PREFIX" ]; then
echo "ERROR: Expected install directory not found: $PREFIX"
has_error=1
else
echo "OK: Found install directory $PREFIX"
fi
# Ensure the compiler is on PATH for the check
if ! command -v x86_64-w64-mingw32-g++ >/dev/null 2>&1; then
export PATH="$PREFIX/bin:$PATH"
fi
# Check compiler exists and version matches expected major.minor (e.g., 14.3)
local gcc_out=""
local gcc_short_ver
gcc_short_ver="${GCC_VER%.*}"
if ! gcc_out="$(x86_64-w64-mingw32-g++ --version 2>/dev/null)"; then
echo "ERROR: x86_64-w64-mingw32-g++ is not runnable or not found on PATH"
has_error=1
else
if echo "$gcc_out" | grep -q "$gcc_short_ver"; then
echo "OK: x86_64-w64-mingw32-g++ version contains $gcc_short_ver"
else
echo "ERROR: x86_64-w64-mingw32-g++ version does not contain $gcc_short_ver"
echo "$gcc_out" | head -n1
has_error=1
fi
fi
# Check DLLs in src-tauri directory
local missing_dlls=()
for dll in libstdc++-6.dll libgcc_s_seh-1.dll; do
if [ ! -f "$SRC_TAURI_DIR/$dll" ]; then
missing_dlls+=("$dll")
fi
done
if [ ${#missing_dlls[@]} -eq 0 ]; then
echo "OK: Required DLLs are present in $SRC_TAURI_DIR"
else
echo "ERROR: Missing DLLs in $SRC_TAURI_DIR: ${missing_dlls[*]}"
echo "Hint: run `just prepare-windows-build` to build and copy the required DLLs"
has_error=1
fi
if [ "$has_error" -eq 0 ]; then
echo "Verification successful"
return 0
else
echo "Verification failed"
return 1
fi
}
if [ -n "${ONLY_WINPTHREADS}" ]; then
echo "ONLY_WINPTHREADS set; building winpthreads.dll"
install_deps
download_sources
build_winpthreads
exit 0
fi
if [ -n "${ONLY_COPY_DLLS}" ]; then
echo "ONLY_COPY_DLLS set; copying dll's to src-tauri/"
copy_dlls
exit 0
fi
if [ -n "${ONLY_VERIFY}" ]; then
verify_installation
exit 0
fi
install_deps
download_sources
build_binutils
build_mingw_headers
prepare_gcc_build
build_mingw_crt
finish_gcc
build_winpthreads
copy_dlls
setup_path
verify_installation
echo "Done"

View file

@ -25,7 +25,8 @@
"**/node_modules/**", "**/node_modules/**",
"**/dist/**", "**/dist/**",
"monero-seed/**", "monero-seed/**",
"monero-sys/monero_c" "monero-sys/monero_c",
"monero-sys/monero"
], ],
"plugins": [ "plugins": [
"https://plugins.dprint.dev/markdown-0.18.0.wasm", "https://plugins.dprint.dev/markdown-0.18.0.wasm",

View file

@ -7,9 +7,10 @@ help:
# just update_submodules # just update_submodules
# cd monero-sys/monero && make -j8 release # cd monero-sys/monero && make -j8 release
# Clean the Monero C++ Codebase # Clean the Monero C++ Codebase and build cache
clean_monero_cpp: clean:
rm -rf monero-sys/monero/ cargo clean
cd monero-sys && rm -rf monero monero_c
just update_submodules just update_submodules
# Builds the Rust bindings for Monero # Builds the Rust bindings for Monero
@ -26,10 +27,10 @@ test-ffi-address:
# Start the Tauri app # Start the Tauri app
tauri: tauri:
cd src-tauri && cargo tauri dev --no-watch --verbose -- -- --testnet cd src-tauri && cargo tauri dev --no-watch -- --verbose -- --testnet
tauri-mainnet: tauri-mainnet:
cd src-tauri && cargo tauri dev --no-watch cd src-tauri && cargo tauri dev --no-watch -- -vv
# Install the GUI dependencies # Install the GUI dependencies
gui_install: gui_install:
@ -49,6 +50,9 @@ gui-mainnet:
gui_build: gui_build:
cd src-gui && yarn build cd src-gui && yarn build
build-gui-windows:
cargo tauri build --target x86_64-pc-windows-gnu -- -vv
# Run the Rust tests # Run the Rust tests
tests: tests:
cargo nextest run cargo nextest run
@ -115,3 +119,6 @@ prepare_mac_os_brew_dependencies:
# E.g code2prompt . --exclude "*.lock" --exclude ".sqlx/*" --exclude "target" # E.g code2prompt . --exclude "*.lock" --exclude ".sqlx/*" --exclude "target"
code2prompt_single_crate crate: code2prompt_single_crate crate:
cd {{crate}} && code2prompt . --exclude "*.lock" --exclude ".sqlx/*" --exclude "target" cd {{crate}} && code2prompt . --exclude "*.lock" --exclude ".sqlx/*" --exclude "target"
prepare-windows-build:
cd dev_scripts && ./ubuntu_build_x86_86-w64-mingw32-gcc.sh

View file

@ -7,7 +7,7 @@ edition = "2018"
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"
futures = { workspace = true } futures = { workspace = true }
libp2p = { workspace = true, default-features = false, features = ["rendezvous", "tcp", "yamux", "dns", "noise", "ping", "websocket", "tokio", "macros"] } libp2p = { workspace = true, features = ["rendezvous", "tcp", "yamux", "dns", "noise", "ping", "websocket", "tokio", "macros"] }
libp2p-tor = { path = "../libp2p-tor", features = ["listen-onion-service"] } libp2p-tor = { path = "../libp2p-tor", features = ["listen-onion-service"] }
tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros", "sync", "process", "fs", "net", "io-util"] } tokio = { workspace = true, features = ["rt-multi-thread", "time", "macros", "sync", "process", "fs", "net", "io-util"] }
tor-hsservice = { workspace = true } tor-hsservice = { workspace = true }

View file

@ -24,7 +24,7 @@ curve25519-dalek = { version = "4", default-features = false, features = ["alloc
[dev-dependencies] [dev-dependencies]
hex = { version = "0.4", default-features = false, features = ["std"] } hex = { version = "0.4", default-features = false, features = ["std"] }
monero-primitives = { git = "https://github.com/serai-dex/serai", default-features = false, features = ["std"] } monero-oxide = { git = "https://github.com/monero-oxide/monero-oxide", default-features = false, features = ["std"] }
[features] [features]
std = [ std = [

View file

@ -44,7 +44,11 @@ The bridge between Rust and the Monero C++ code works as follows:
2. **C++ Adapter (bridge.h)**: 2. **C++ Adapter (bridge.h)**:
- Contains helper functions to work around CXX limitations - Contains helper functions to work around CXX limitations
- Provides wrappers for static methods (like `getWalletManager()`) - Provides wrappers for static methods (like `getWalletManager()`)
- Handles string returns with `std::unique_ptr<std::string>` - CXX can't handle some C++ types being returned by value (especially `std::string` and `std::vector`), so we wrap them in a pointer:
- if we know we are the owner of the value we use `std::unique_ptr<T>`
- if we don't know we use `std::shared_ptr<T>`
- in the case of `TransactionHistory` we use a raw pointer because we aren't the only owner of the value but also need to mutate it.
Such uses have to be manually verified!
3. **Rust Wrapper (lib.rs)**: 3. **Rust Wrapper (lib.rs)**:
- Provides idiomatic Rust interfaces to the C++ code - Provides idiomatic Rust interfaces to the C++ code
@ -63,7 +67,8 @@ The bridge between Rust and the Monero C++ code works as follows:
5. **Memory Safety Model**: 5. **Memory Safety Model**:
- Raw pointers are wrapped in safe Rust types - Raw pointers are wrapped in safe Rust types
- `unsafe` is only used at the FFI boundary - `unsafe` is only used at the FFI boundary
- Proper deref implementations for wrapper types - Each use of `unsafe` must have a `// Safety: ...` comment explaining why every required invariant is upheld.
- Proper deref implementations for wrapper types (`impl Deref for RawWallet { type Target = ffi::Wallet; fn deref(&self) -> &Self::Target { unsafe { self.inner.as_ref().expect("RawWallet is not null") } } }`)
- The `OnceLock` pattern ensures WalletManager is a singleton - The `OnceLock` pattern ensures WalletManager is a singleton
6. **Adding New Functionality**: 6. **Adding New Functionality**:
@ -71,5 +76,17 @@ The bridge between Rust and the Monero C++ code works as follows:
2. Add its declaration to the `unsafe extern "C++"` block in bridge.rs 2. Add its declaration to the `unsafe extern "C++"` block in bridge.rs
3. Create a corresponding Rust wrapper method in lib.rs 3. Create a corresponding Rust wrapper method in lib.rs
4. For functions returning strings or with other CXX limitations, add helper functions in bridge.h 4. For functions returning strings or with other CXX limitations, add helper functions in bridge.h
7. **Ensuring Memory Safety**:
- *`Send and Sync`*:
- Don't `unsafe impl Sync`, it's never needed. Work around limitaions if necessary.
- You can `unsafe impl Send` for a Rust wrapper type *if* you verified that the type is safe to be moved around threads:
- By default, assume that *no type is `Send`*
- A type is *not `Send`* if it contains a reference/pointer to a non-`Send` type -- notably, `Wallet` and `WalletManager` are not `Send`
- A type is *not `Send`* if it uses thread local storage (`WalletManager` and `Wallet`)
- A type *is `Send`* if it contains only basic types: integers, strings, vectors of other basic types or other `Send` types.
- Never implement `Send` unless you have specifically verified that the type actually is.
- Even if it would be possible, try to avoid implementing `Send` if possible. For example, instead of implementing `unsafe impl Send for TransactionInfoHandle` we immediately copy the values it conaints into our own, Rust-native `TransactionInfo` struct.
This architecture ensures memory safety while providing idiomatic access to the Monero wallet functionality from Rust. This architecture ensures memory safety while providing idiomatic access to the Monero wallet functionality from Rust.

View file

@ -27,6 +27,7 @@ uuid = { workspace = true }
cmake = "0.1.54" cmake = "0.1.54"
cxx-build = "1.0.137" cxx-build = "1.0.137"
diffy = "0.4.2" diffy = "0.4.2"
fs_extra = "1.3.0"
[dev-dependencies] [dev-dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }

View file

@ -1,5 +1,7 @@
use cmake::Config; use cmake::Config;
use fs_extra::error::ErrorKind;
use std::fs; use std::fs;
use std::io::Write as _;
use std::path::Path; use std::path::Path;
/// Represents a patch to be applied to the Monero codebase /// Represents a patch to be applied to the Monero codebase
@ -27,6 +29,26 @@ const EMBEDDED_PATCHES: &[EmbeddedPatch] = &[
"Adds subtract_fee_from_outputs parameter to wallet2_api transaction creation methods", "Adds subtract_fee_from_outputs parameter to wallet2_api transaction creation methods",
"patches/eigenwallet_0001_wallet2_api_allow_subtract_from_fee.patch" "patches/eigenwallet_0001_wallet2_api_allow_subtract_from_fee.patch"
), ),
embedded_patch!(
"0001-fix-dummy-translation-generator.patch",
"Creates dummy translation generator",
"patches/0001-fix-dummy-translation-generator.patch"
),
embedded_patch!(
"0002-fix-iOS-depends-build.patch",
"Fixes iOS depends build",
"patches/0002-fix-iOS-depends-build.patch"
),
embedded_patch!(
"0003-include-locale-only-when-targeting-WIN32.patch",
"Includes locale only when targeting WIN32 to fix cross-platform build issues",
"patches/0003-include-locale-only-when-targeting-WIN32.patch"
),
embedded_patch!(
"0004-fix-___isPlatformVersionAtLeast.patch",
"Fixes ___isPlatformVersionAtLeast being called",
"patches/0004-fix-___isPlatformVersionAtLeast.patch"
),
embedded_patch!( embedded_patch!(
"0002-store-crash-fix", "0002-store-crash-fix",
"Fixes corrupted wallet cache when storing while refreshing", "Fixes corrupted wallet cache when storing while refreshing",
@ -43,7 +65,7 @@ fn main() {
let is_github_actions: bool = std::env::var("GITHUB_ACTIONS").is_ok(); let is_github_actions: bool = std::env::var("GITHUB_ACTIONS").is_ok();
let is_docker_build: bool = std::env::var("DOCKER_BUILD").is_ok(); let is_docker_build: bool = std::env::var("DOCKER_BUILD").is_ok();
// Eerun this when the bridge.rs or static_bridge.h file changes. // Rerun this when the bridge.rs or static_bridge.h file changes.
println!("cargo:rerun-if-changed=src/bridge.rs"); println!("cargo:rerun-if-changed=src/bridge.rs");
println!("cargo:rerun-if-changed=src/bridge.h"); println!("cargo:rerun-if-changed=src/bridge.h");
@ -54,11 +76,38 @@ fn main() {
println!("cargo:rerun-if-changed=patches"); println!("cargo:rerun-if-changed=patches");
// Apply embedded patches before building // Apply embedded patches before building
apply_embedded_patches().expect("Failed to apply embedded patches"); apply_patches().expect("Failed to apply our patches");
// flush std::out
std::io::stdout().flush().unwrap();
std::io::stderr().flush().unwrap();
let contrib_depends_dir = std::env::current_dir()
.expect("current directory to be accessible")
.join("monero_c/contrib/depends");
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR to be set");
let out_dir = Path::new(&out_dir);
let (contrib_depends_dir, target) =
compile_dependencies(contrib_depends_dir, out_dir.join("depends"));
// Build with the monero library all dependencies required // Build with the monero library all dependencies required
let mut config = Config::new("monero"); let mut config = Config::new("monero");
let toolchain_file = contrib_depends_dir
.join(format!("{}/share/toolchain.cmake", target))
.display()
.to_string();
config.define("CMAKE_TOOLCHAIN_FILE", toolchain_file.clone());
println!("cargo:warning=Using toolchain file: {}", toolchain_file);
let depends_lib_dir = contrib_depends_dir.join(format!("{}/lib", target));
println!(
"cargo:rustc-link-search=native={}",
depends_lib_dir.display()
);
let output_directory = config let output_directory = config
.build_target("wallet_api") .build_target("wallet_api")
// Builds currently fail in Release mode // Builds currently fail in Release mode
@ -68,10 +117,6 @@ fn main() {
.define("STATIC", "ON") .define("STATIC", "ON")
.define("BUILD_SHARED_LIBS", "OFF") .define("BUILD_SHARED_LIBS", "OFF")
.define("BUILD_TESTS", "OFF") .define("BUILD_TESTS", "OFF")
.define("Boost_USE_STATIC_LIBS", "ON")
.define("Boost_USE_STATIC_RUNTIME", "ON")
//// Disable support for ALL hardware wallets
// Disable Trezor support completely
.define("USE_DEVICE_TREZOR", "OFF") .define("USE_DEVICE_TREZOR", "OFF")
.define("USE_DEVICE_TREZOR_MANDATORY", "OFF") .define("USE_DEVICE_TREZOR_MANDATORY", "OFF")
.define("USE_DEVICE_TREZOR_PROTOBUF_TEST", "OFF") .define("USE_DEVICE_TREZOR_PROTOBUF_TEST", "OFF")
@ -85,14 +130,24 @@ fn main() {
.define("USE_DEVICE_LEDGER", "OFF") .define("USE_DEVICE_LEDGER", "OFF")
.define("CMAKE_DISABLE_FIND_PACKAGE_HIDAPI", "ON") .define("CMAKE_DISABLE_FIND_PACKAGE_HIDAPI", "ON")
.define("GTEST_HAS_ABSL", "OFF") .define("GTEST_HAS_ABSL", "OFF")
.define("SODIUM_LIBRARY", "libsodium.a")
// Use lightweight crypto library // Use lightweight crypto library
.define("MONERO_WALLET_CRYPTO_LIBRARY", "cn") .define("MONERO_WALLET_CRYPTO_LIBRARY", "cn")
.define("CMAKE_CROSSCOMPILING", "OFF")
.define(
"SODIUM_INCLUDE_PATH",
contrib_depends_dir
.join(format!("{}/include", target))
.display()
.to_string(),
) // This is needed for libsodium.a to be found on mingw-w64
.build_arg("-Wno-dev") // Disable warnings we can't fix anyway .build_arg("-Wno-dev") // Disable warnings we can't fix anyway
.build_arg(match (is_github_actions, is_docker_build) { .build_arg(match (is_github_actions, is_docker_build) {
(true, _) => "-j1", (true, _) => "-j1",
(_, true) => "-j1", (_, true) => "-j1",
(_, _) => "-j4", (_, _) => "-j4",
}) })
.build_arg(format!("-I."))
.build(); .build();
let monero_build_dir = output_directory.join("build"); let monero_build_dir = output_directory.join("build");
@ -127,8 +182,13 @@ fn main() {
"cargo:rustc-link-search=native={}", "cargo:rustc-link-search=native={}",
monero_build_dir.join("external/randomx").display() monero_build_dir.join("external/randomx").display()
); );
println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu");
println!("cargo:rustc-link-search=native=/usr/lib/aarch64-linux-gnu"); if target.contains("linux") && target.contains("x86_64") {
println!("cargo:rustc-link-search=native=/usr/lib/x86_64-linux-gnu");
}
if target.contains("linux") && target.contains("aarch64") {
println!("cargo:rustc-link-search=native=/usr/lib/aarch64-linux-gnu");
}
println!( println!(
"cargo:rustc-link-search=native={}", "cargo:rustc-link-search=native={}",
@ -192,8 +252,8 @@ fn main() {
monero_build_dir.join("src/rpc").display() monero_build_dir.join("src/rpc").display()
); );
#[cfg(target_os = "macos")] // Add search paths for clang runtime libraries on macOS (not iOS)
{ if target.contains("apple-darwin") {
// Dynamically detect Homebrew installation prefix (works on both Apple Silicon and Intel Macs) // Dynamically detect Homebrew installation prefix (works on both Apple Silicon and Intel Macs)
let brew_prefix = std::process::Command::new("brew") let brew_prefix = std::process::Command::new("brew")
.arg("--prefix") .arg("--prefix")
@ -229,9 +289,9 @@ fn main() {
println!("cargo:rustc-link-lib=static=clang_rt.osx"); println!("cargo:rustc-link-lib=static=clang_rt.osx");
} }
// Link libwallet and libwallet_api statically // Link libwallet_api before libwallet for correct static link resolution on GNU ld
println!("cargo:rustc-link-lib=static=wallet");
println!("cargo:rustc-link-lib=static=wallet_api"); println!("cargo:rustc-link-lib=static=wallet_api");
println!("cargo:rustc-link-lib=static=wallet");
// Link targets of monero codebase statically // Link targets of monero codebase statically
println!("cargo:rustc-link-lib=static=epee"); println!("cargo:rustc-link-lib=static=epee");
@ -262,22 +322,41 @@ fn main() {
println!("cargo:rustc-link-lib=static=boost_filesystem"); println!("cargo:rustc-link-lib=static=boost_filesystem");
println!("cargo:rustc-link-lib=static=boost_thread"); println!("cargo:rustc-link-lib=static=boost_thread");
println!("cargo:rustc-link-lib=static=boost_chrono"); println!("cargo:rustc-link-lib=static=boost_chrono");
println!("cargo:rustc-link-lib=static=boost_program_options");
if target.contains("w64-mingw32") {
println!("cargo:rustc-link-lib=static=boost_locale");
println!("cargo:rustc-link-lib=static=iconv");
// Link C++ standard library and GCC runtime statically
println!("cargo:rustc-link-arg=-static-libstdc++");
println!("cargo:rustc-link-arg=-static-libgcc");
}
// Link libsodium statically // Link libsodium statically
println!("cargo:rustc-link-lib=static=sodium"); println!("cargo:rustc-link-lib=static=sodium");
// Link OpenSSL statically // Link OpenSSL statically (on android we use openssl-sys's vendored version instead)
println!("cargo:rustc-link-lib=static=ssl"); // This is OpenSSL (libsll) #[cfg(not(target_os = "android"))]
println!("cargo:rustc-link-lib=static=crypto"); // This is OpenSSLs crypto library (libcrypto) {
println!("cargo:rustc-link-lib=static=ssl"); // This is OpenSSL (libsll)
println!("cargo:rustc-link-lib=static=crypto"); // This is OpenSSLs crypto library (libcrypto)
}
// Link unbound statically // Link unbound statically
println!("cargo:rustc-link-lib=static=unbound"); println!("cargo:rustc-link-lib=static=unbound");
println!("cargo:rustc-link-lib=static=expat"); // Expat is required by unbound println!("cargo:rustc-link-lib=static=expat"); // Expat is required by unbound
println!("cargo:rustc-link-lib=static=nghttp2"); // println!("cargo:rustc-link-lib=static=nghttp2");
println!("cargo:rustc-link-lib=static=event"); // println!("cargo:rustc-link-lib=static=event");
// Android
#[cfg(target_os = "android")]
{
println!("cargo:rustc-link-search=/home/me/Android/Sdk/ndk/27.3.13750724/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/aarch64-linux-android/");
// println!("cargo:rustc-link-lib=static=c++_static");
}
// Link protobuf statically // Link protobuf statically
println!("cargo:rustc-link-lib=static=protobuf"); // println!("cargo:rustc-link-lib=static=protobuf");
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
println!("cargo:rustc-link-arg=-mmacosx-version-min=11.0"); println!("cargo:rustc-link-arg=-mmacosx-version-min=11.0");
@ -285,9 +364,12 @@ fn main() {
// Build the CXX bridge // Build the CXX bridge
let mut build = cxx_build::bridge("src/bridge.rs"); let mut build = cxx_build::bridge("src/bridge.rs");
#[cfg(target_os = "macos")] if target.contains("apple-ios") {
{ // required for ___chkstk_darwin to be available
build.flag_if_supported("-mmacosx-version-min=11.0"); build.flag_if_supported("-mios-version-min=13.0");
println!("cargo:rustc-link-arg=-mios-version-min=13.0");
println!("cargo:rustc-link-lib=framework=SystemConfiguration");
println!("cargo:rustc-env=IPHONEOS_DEPLOYMENT_TARGET=13.0");
} }
build build
@ -296,24 +378,209 @@ fn main() {
.include("monero/src") // Includes the monero headers .include("monero/src") // Includes the monero headers
.include("monero/external/easylogging++") // Includes the easylogging++ headers .include("monero/external/easylogging++") // Includes the easylogging++ headers
.include("monero/contrib/epee/include") // Includes the epee headers for net/http_client.h .include("monero/contrib/epee/include") // Includes the epee headers for net/http_client.h
.include("/opt/homebrew/include") // Homebrew include path for Boost .include(
contrib_depends_dir
.join(format!("{}/include", target))
.display()
.to_string(),
)
.include(output_directory)
.flag("-fPIC"); // Position independent code .flag("-fPIC"); // Position independent code
#[cfg(target_os = "macos")] build.compile("monero-sys");
{ }
// Use the same dynamic brew prefix for include paths
let brew_prefix = std::process::Command::new("brew")
.arg("--prefix")
.output()
.ok()
.and_then(|o| String::from_utf8(o.stdout).ok())
.map(|s| s.trim().to_string())
.unwrap_or_else(|| "/opt/homebrew".into());
build.include(format!("{}/include", brew_prefix)); // Homebrew include path for Boost /// Compile the dependencies
fn compile_dependencies(
contrib_depends: std::path::PathBuf,
out_dir: std::path::PathBuf,
) -> (std::path::PathBuf, String) {
let mut target = std::env::var("TARGET").unwrap_or_else(|_| "unknown".to_string());
target = match target.as_str() {
"aarch64-unknown-linux-gnu" => "aarch64-linux-gnu".to_string(),
"armv7-linux-androideabi" => "armv7a-linux-androideabi".to_string(),
"x86_64-pc-windows-gnu" => "x86_64-w64-mingw32".to_string(),
"aarch64-apple-ios-sim" => "aarch64-apple-iossimulator".to_string(),
_ => target,
};
println!("cargo:warning=Building for target: {}", target);
match target.as_str() {
"x86_64-apple-darwin"
| "aarch64-apple-darwin"
| "aarch64-apple-ios"
| "aarch64-apple-iossimulator"
| "x86_64-unknown-linux-gnu"
| "aarch64-linux-gnu"
| "aarch64-linux-android"
| "x86_64-linux-android"
| "armv7a-linux-androideabi"
| "x86_64-w64-mingw32" => {}
_ => panic!("target unsupported: {}", target),
} }
build.compile("monero-sys"); println!(
"cargo:warning=Running make HOST={} in contrib/depends",
target
);
// Copy monero_c/contrib/depends to out_dir/depends in order to build the dependencies there
match fs_extra::copy_items(
&[&contrib_depends],
&out_dir,
&fs_extra::dir::CopyOptions::new().copy_inside(true),
) {
Ok(_) => (),
Err(e) if matches!(e.kind, ErrorKind::AlreadyExists) => (), // Ignore the error if the directory already exists
Err(e) => {
eprintln!("Failed to copy contrib/depends to target dir: {}", e);
std::process::exit(1);
}
}
let mut cmd = std::process::Command::new("env");
if target.contains("-apple-") {
cmd.arg("-i");
let path = std::env::var("PATH").unwrap_or_default();
cmd.arg(format!("PATH={}", path));
}
cmd.arg("make")
.arg(format!("HOST={}", target))
.arg("DEBUG=")
.current_dir(&out_dir)
.stdout(std::process::Stdio::piped())
.stderr(std::process::Stdio::piped());
let child = cmd
.spawn()
.expect("[make depends] make command to be executable");
let status = execute_child_with_pipe(child, String::from("[make depends] "))
.expect("[make depends] make command to execute");
if !status.success() {
panic!(
"[make depends] command failed with exit code: {:?}",
status.code()
);
}
println!("cargo:info=[make depends] make command completed successfully");
(out_dir, target)
}
/// Execute a child process with piped stdout/stderr and display output in real-time
fn execute_child_with_pipe(
mut child: std::process::Child,
prefix: String,
) -> Result<std::process::ExitStatus, Box<dyn std::error::Error>> {
use std::io::{BufRead, BufReader};
use std::thread;
let stdout = child.stdout.take().expect("Failed to get stdout");
let stderr = child.stderr.take().expect("Failed to get stderr");
let prefix_clone = prefix.clone();
// Spawn threads to handle stdout and stderr
let stdout_handle = thread::spawn(move || {
let reader = BufReader::new(stdout);
for line in reader.lines() {
if let Ok(line) = line {
println!("cargo:debug={}{}", &prefix_clone, line);
}
}
});
let stderr_handle = thread::spawn(move || {
let reader = BufReader::new(stderr);
for line in reader.lines() {
if let Ok(line) = line {
println!("cargo:debug={}{}", &prefix, line);
}
}
});
// Wait for the process to complete
let status = child.wait()?;
// Wait for output threads to complete
stdout_handle.join().unwrap();
stderr_handle.join().unwrap();
Ok(status)
}
/// Applies the [`EMBEDDED_PATCHES`] to the monero codebase.
fn apply_patches() -> Result<(), Box<dyn std::error::Error>> {
let monero_dir = Path::new("monero");
if !monero_dir.exists() {
return Err("Monero directory not found. Please ensure the monero submodule is initialized and present.".into());
}
for embedded in EMBEDDED_PATCHES {
println!(
"cargo:warning=Processing embedded patch: {} ({})",
embedded.name, embedded.description
);
// Split the patch into individual file patches
let file_patches = split_patch_by_files(embedded.patch_unified)
.map_err(|e| format!("Failed to split patch {}: {}", embedded.name, e))?;
if file_patches.is_empty() {
return Err(format!("No file patches found in patch {}", embedded.name).into());
}
println!(
"cargo:warning=Found {} file(s) in patch {}",
file_patches.len(),
embedded.name
);
// Apply each file patch individually
for (file_path, patch_content) in file_patches {
println!("cargo:warning=Applying patch to file: {}", file_path);
// Parse the individual file patch
let patch = diffy::Patch::from_str(&patch_content)
.map_err(|e| format!("Failed to parse patch for {}: {}", file_path, e))?;
let target_path = monero_dir.join(&file_path);
if !target_path.exists() {
return Err(format!("Target file {} not found!", file_path).into());
}
let current = fs::read_to_string(&target_path)
.map_err(|e| format!("Failed to read {}: {}", file_path, e))?;
// Check if patch is already applied by trying to reverse it
if diffy::apply(&current, &patch.reverse()).is_ok() {
println!(
"cargo:warning=Patch for {} already applied skipping",
file_path
);
continue;
}
let patched = diffy::apply(&current, &patch)
.map_err(|e| format!("Failed to apply patch to {}: {}", file_path, e))?;
fs::write(&target_path, patched)
.map_err(|e| format!("Failed to write {}: {}", file_path, e))?;
println!("cargo:warning=Successfully applied patch to: {}", file_path);
}
println!(
"cargo:warning=Successfully applied all file patches for: {} ({})",
embedded.name, embedded.description
);
}
Ok(())
} }
/// Split a multi-file patch into individual file patches /// Split a multi-file patch into individual file patches
@ -363,82 +630,3 @@ fn split_patch_by_files(
Ok(file_patches) Ok(file_patches)
} }
fn apply_embedded_patches() -> Result<(), Box<dyn std::error::Error>> {
let monero_dir = Path::new("monero");
if !monero_dir.exists() {
return Err("Monero directory not found. Please ensure the monero submodule is initialized and present.".into());
}
for embedded in EMBEDDED_PATCHES {
println!(
"cargo:warning=Processing embedded patch: {} ({})",
embedded.name, embedded.description
);
// Split the patch into individual file patches
let file_patches = split_patch_by_files(embedded.patch_unified)
.map_err(|e| format!("Failed to split patch {}: {}", embedded.name, e))?;
if file_patches.is_empty() {
return Err(format!("No file patches found in patch {}", embedded.name).into());
}
println!(
"cargo:warning=Found {} file(s) in patch {}",
file_patches.len(),
embedded.name
);
// Apply each file patch individually
for (file_path, patch_content) in file_patches {
println!("cargo:warning=Applying patch to file: {}", file_path);
// Parse the individual file patch
let patch = diffy::Patch::from_str(&patch_content)
.map_err(|e| format!("Failed to parse patch for {}: {}", file_path, e))?;
let target_path = monero_dir.join(&file_path);
if !target_path.exists() {
return Err(format!("Target file {} not found!", file_path).into());
}
let current = fs::read_to_string(&target_path)
.map_err(|e| format!("Failed to read {}: {}", file_path, e))?;
let patched = match diffy::apply(&current, &patch) {
Ok(p) => p,
Err(_) => {
// Try reversing the patch if that succeeds the file already contains the changes
if diffy::apply(&current, &patch.reverse()).is_ok() {
println!(
"cargo:warning=Patch for {} already applied skipping",
file_path
);
continue;
} else {
return Err(format!(
"Failed to apply patch to {}: hunk mismatch (not already applied)",
file_path
)
.into());
}
}
};
fs::write(&target_path, patched)
.map_err(|e| format!("Failed to write {}: {}", file_path, e))?;
println!("cargo:warning=Successfully applied patch to: {}", file_path);
}
println!(
"cargo:warning=Successfully applied all file patches for: {} ({})",
embedded.name, embedded.description
);
}
Ok(())
}

@ -1 +1 @@
Subproject commit 5f714f147fd29228698070e6bd80e41ce2f86fb0 Subproject commit dbbccecc89e1121762a4ad6b531638ece82aa0c7

1
monero-sys/monero_c Submodule

@ -0,0 +1 @@
Subproject commit 2af8a21dbc3db36d77c29de90d6d0a85c912255e

View file

@ -0,0 +1,70 @@
From 953bb8df6beefd9f5897521b4678e8e0955c4713 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 14 Jul 2025 23:19:35 +0200
Subject: [PATCH] fix: dummy translation generator
---
CMakeLists.txt | 35 ++++++++++++++++++++++++++---------
src/common/CMakeLists.txt | 3 +--
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 46bd5eb1b..7301f76d6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -664,15 +664,32 @@ function (monero_add_library_with_deps)
endfunction ()
# Generate header for embedded translations
-# Generate header for embedded translations, use target toolchain if depends, otherwise use the
-# lrelease and lupdate binaries from the host
-include(ExternalProject)
-ExternalProject_Add(generate_translations_header
- SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/translations"
- BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/translations"
- STAMP_DIR ${LRELEASE_PATH}
- CMAKE_ARGS -DLRELEASE_PATH=${LRELEASE_PATH}
- INSTALL_COMMAND ${CMAKE_COMMAND} -E echo "")
+file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/translations/translation_files.h"
+"#ifndef TRANSLATION_FILES_H
+#define TRANSLATION_FILES_H
+
+#include <string>
+
+static const struct embedded_file {
+ const std::string *name;
+ const std::string *data;
+} embedded_files[] = {
+ {NULL, NULL}
+};
+
+static bool find_embedded_file(const std::string &name, std::string &data) {
+ const struct embedded_file *p;
+ for (p = embedded_files; p->name != NULL; p++) {
+ if (*p->name == name) {
+ data = *p->data;
+ return true;
+ }
+ }
+ return false;
+}
+
+#endif /* TRANSLATION_FILES_H */
+")
include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations")
add_subdirectory(external)
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index b712ee6b1..a1dff7e5d 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -65,8 +65,7 @@ monero_private_headers(common
monero_add_library(common
${common_sources}
${common_headers}
- ${common_private_headers}
- DEPENDS generate_translations_header)
+ ${common_private_headers})
target_link_libraries(common
PUBLIC
cncrypto

View file

@ -0,0 +1,101 @@
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/17] 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)
include(CheckFunctionExists)
include(FindPythonInterp)
-if (IOS)
- INCLUDE(CmakeLists_IOS.txt)
-endif()
-
cmake_minimum_required(VERSION 3.5)
message(STATUS "CMake version ${CMAKE_VERSION}")
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);

View file

@ -0,0 +1,38 @@
From 6d9116c6d57d72f9bab5d28740209ffdefc9d197 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Mon, 18 Nov 2024 10:57:37 -0500
Subject: [PATCH] include locale only when targeting WIN32
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 46bd5eb1b..d5cfecf39 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1085,7 +1085,11 @@ if(NOT Boost_FOUND)
elseif(Boost_FOUND)
message(STATUS "Found Boost Version: ${Boost_VERSION_STRING}")
- set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options locale)
+ set(BOOST_COMPONENTS filesystem thread date_time chrono serialization program_options)
+
+ if(WIN32)
+ list(APPEND BOOST_COMPONENTS locale)
+ endif()
# 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 96393eaaa..b6f527ae5 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -48,7 +48,10 @@
#include <sstream>
#include <unordered_map>
+#ifdef WIN32
#include <boost/locale.hpp>
+#endif
+
#include <boost/filesystem.hpp>
using namespace std;

View file

@ -0,0 +1,22 @@
From 1ac620cf1afd6515daa127039311ba9c9a2a1ea3 Mon Sep 17 00:00:00 2001
From: Czarek Nakamoto <cyjan@mrcyjanek.net>
Date: Tue, 15 Jul 2025 19:58:34 +0200
Subject: [PATCH] fix: ___isPlatformVersionAtLeast
---
src/virtual_memory.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/external/randomx/src/virtual_memory.c b/external/randomx/src/virtual_memory.c
index d2cdcda..5158ea4 100644
--- a/external/randomx/src/virtual_memory.c
+++ b/external/randomx/src/virtual_memory.c
@@ -35,7 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <TargetConditionals.h>
#include <AvailabilityMacros.h>
# if TARGET_OS_OSX
-# define USE_PTHREAD_JIT_WP 1
+# define USE_PTHREAD_JIT_WP 0
# include <pthread.h>
# include <sys/utsname.h>
# include <stdio.h>

View file

@ -9,6 +9,8 @@
- For formatting and bindings: `dprint` (`cargo install dprint@0.50.0`) and `typeshare` (`cargo install typeshare-cli`) - For formatting and bindings: `dprint` (`cargo install dprint@0.50.0`) and `typeshare` (`cargo install typeshare-cli`)
- If you are on Windows and you want to use the `check-bindings` command you'll need to manually install the GNU DiffUtils ([installation](https://gnuwin32.sourceforge.net/packages/diffutils.htm)) and GNU CoreUtils ([installtion](https://gnuwin32.sourceforge.net/packages/coreutils.htm)). Remember to add the installation path (probably `C:\Program Files (x86)\GnuWin32\bin`) to the `PATH` in your enviroment variables. - If you are on Windows and you want to use the `check-bindings` command you'll need to manually install the GNU DiffUtils ([installation](https://gnuwin32.sourceforge.net/packages/diffutils.htm)) and GNU CoreUtils ([installtion](https://gnuwin32.sourceforge.net/packages/coreutils.htm)). Remember to add the installation path (probably `C:\Program Files (x86)\GnuWin32\bin`) to the `PATH` in your enviroment variables.
- Compiling for Windows is only possible from Ubuntu (x86_64). It requires a very recent mingw version which you'll need to build from source. You can do this by running `just prepare-windows-build` from the root of the repository.
## Start development servers ## Start development servers
For development, we need to run both `vite` and `tauri` servers: For development, we need to run both `vite` and `tauri` servers:

7748
src-gui/package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -24,15 +24,15 @@
"@mui/material": "^7.1.1", "@mui/material": "^7.1.1",
"@mui/x-date-pickers": "^8.8.0", "@mui/x-date-pickers": "^8.8.0",
"@reduxjs/toolkit": "^2.3.0", "@reduxjs/toolkit": "^2.3.0",
"@tauri-apps/api": "^2.0.0", "@tauri-apps/api": "^2.8.0",
"@tauri-apps/plugin-cli": "^2.0.0", "@tauri-apps/plugin-cli": "^2.4.0",
"@tauri-apps/plugin-clipboard-manager": "^2.0.0", "@tauri-apps/plugin-clipboard-manager": "^2.3.0",
"@tauri-apps/plugin-dialog": "^2.0.0", "@tauri-apps/plugin-dialog": "^2.0.0",
"@tauri-apps/plugin-opener": "^2.0.0", "@tauri-apps/plugin-opener": "^2.5.0",
"@tauri-apps/plugin-process": "^2.0.0", "@tauri-apps/plugin-process": "^2.3.0",
"@tauri-apps/plugin-shell": "^2.0.0", "@tauri-apps/plugin-shell": "^2.3.0",
"@tauri-apps/plugin-store": "^2.0.0", "@tauri-apps/plugin-store": "^2.4.0",
"@tauri-apps/plugin-updater": "2.7.1", "@tauri-apps/plugin-updater": "^2.9.0",
"@types/react-redux": "^7.1.34", "@types/react-redux": "^7.1.34",
"boring-avatars": "^1.11.2", "boring-avatars": "^1.11.2",
"dayjs": "^1.11.13", "dayjs": "^1.11.13",

View file

@ -1,9 +1,16 @@
import { ExtendedMakerStatus } from "models/apiModel"; import { ExtendedMakerStatus } from "models/apiModel";
import { splitPeerIdFromMultiAddress } from "utils/parseUtils"; import { splitPeerIdFromMultiAddress } from "utils/parseUtils";
import { getMatches } from "@tauri-apps/plugin-cli"; import { CliMatches, getMatches } from "@tauri-apps/plugin-cli";
import { Network } from "./features/settingsSlice"; import { Network } from "./features/settingsSlice";
const matches = await getMatches(); let matches: CliMatches;
try {
matches = await getMatches();
} catch {
matches = {
args: {},
};
}
export function getNetwork(): Network { export function getNetwork(): Network {
if (isTestnet()) { if (isTestnet()) {

File diff suppressed because it is too large Load diff

View file

@ -5,3 +5,6 @@
# Generated by Tauri # Generated by Tauri
# will have schema files for capabilities auto-completion # will have schema files for capabilities auto-completion
/gen/schemas /gen/schemas
# Tauri windows .dll dependencies - build by `just prepare-windows-build`
*.dll

View file

@ -1,7 +1,7 @@
[package] [package]
name = "unstoppableswap-gui-rs" name = "unstoppableswap-gui-rs"
version = "3.0.0-beta.12" version = "3.0.0-beta.12"
authors = [ "binarybaron", "einliterflasche", "unstoppableswap" ] authors = ["binarybaron", "einliterflasche", "unstoppableswap"]
edition = "2021" edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@ -9,10 +9,10 @@ description = "GUI for XMR<>BTC Atomic Swaps written in Rust"
[lib] [lib]
name = "unstoppableswap_gui_rs_lib" name = "unstoppableswap_gui_rs_lib"
crate-type = [ "lib", "staticlib" ] crate-type = ["rlib", "staticlib", "cdylib"]
[build-dependencies] [build-dependencies]
tauri-build = { version = "^2.0.0", features = [ "config-json5" ] } tauri-build = { version = "2.*", features = ["config-json5"] }
[dependencies] [dependencies]
anyhow = { workspace = true } anyhow = { workspace = true }
@ -20,22 +20,29 @@ monero-rpc-pool = { path = "../monero-rpc-pool" }
rustls = { version = "0.23.26", default-features = false, features = ["ring"] } rustls = { version = "0.23.26", default-features = false, features = ["ring"] }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
swap = { path = "../swap", features = [ "tauri" ] } swap = { path = "../swap", features = ["tauri"] }
tauri = { version = "^2.0.0", features = [ "config-json5" ] } sysinfo = "=0.32.1"
tauri-plugin-clipboard-manager = "^2.0.0" tauri = { version = "2.*", features = ["config-json5"] }
tauri-plugin-dialog = "2.2.2" tauri-cli = "2.*"
tauri-plugin-opener = "^2.0.0" tauri-plugin-clipboard-manager = "2.*"
tauri-plugin-process = "^2.0.0" tauri-plugin-dialog = "2.*"
tauri-plugin-shell = "^2.0.0" tauri-plugin-opener = "2.*"
tauri-plugin-store = "^2.0.0" tauri-plugin-process = "2.*"
tauri-plugin-updater = "^2.0.0" tauri-plugin-shell = "2.*"
tauri-plugin-store = "2.*"
tauri-plugin-updater = "2.*"
tokio = { workspace = true, features = ["rt"] } tokio = { workspace = true, features = ["rt"] }
tokio-util = { version = "0.7", features = ["rt"] } tokio-util = { version = "0.7", features = ["rt"] }
tracing = { workspace = true } tracing = { workspace = true }
uuid = { workspace = true } uuid = { workspace = true }
zip = "4.0.0" zip = { version = "4.0.0", default-features = false }
dfx-swiss-sdk = { git = "https://github.com/eigenwallet/dfx-swiss-rs", subdir = "dfx-swiss-sdk" } dfx-swiss-sdk = { git = "https://github.com/eigenwallet/dfx-swiss-rs" }
[target.aarch64-linux-android.dependencies]
openssl = { version = "0.10", features = [
"vendored",
] } # force use of vendored openssl for android
[target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies] [target."cfg(not(any(target_os = \"android\", target_os = \"ios\")))".dependencies]
tauri-plugin-cli = "^2.0.0" tauri-plugin-cli = "2.*"
tauri-plugin-single-instance = "^2.0.0" tauri-plugin-single-instance = "2.*"

View file

@ -1,3 +1,24 @@
fn main() { fn main() {
tauri_build::build() #[cfg(target_os = "windows")]
{
#[cfg(not(host_os = "linux"))]
{
panic!("Compiling for Windows is currently only supported from Linux (x86_64)");
}
// make sure the .dll's are exist -- else panic
if !["libstdc++-6.dll", "libgcc_s_seh-1.dll"]
.into_iter()
.all(|dll| std::path::Path::new(dll).try_exists().unwrap_or(false))
{
panic!("libstdc++-6.dll and libgcc_s_seh-1.dll don't exist in the src-tauri directory - run `just prepare-windows-build` to build them");
}
let home_dir = std::env::var("HOME").expect("HOME environment variable not set");
let lib_path = format!("{}/opt/gcc-mingw-14.3/x86_64-w64-mingw32/lib", home_dir);
println!("cargo:rustc-link-search=native={}", lib_path);
println!("cargo:rustc-link-lib=stdc++");
}
tauri_build::build();
} }

View file

@ -10,7 +10,6 @@
"shell:allow-open", "shell:allow-open",
"store:default", "store:default",
"process:default", "process:default",
"cli:allow-cli-matches",
"updater:default", "updater:default",
"process:allow-restart", "process:allow-restart",
"opener:default", "opener:default",

View file

@ -1,5 +1,5 @@
{ {
"identifier": "desktop-capability", "identifier": "desktop-capability",
"platforms": ["macOS", "windows", "linux"], "platforms": ["macOS", "windows", "linux"],
"permissions": ["cli:default"] "permissions": ["cli:default", "cli:allow-cli-matches"]
} }

View file

@ -0,0 +1,12 @@
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false

19
src-tauri/gen/android/.gitignore vendored Normal file
View file

@ -0,0 +1,19 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
build
/captures
.externalNativeBuild
.cxx
local.properties
key.properties
/.tauri
/tauri.settings.gradle

6
src-tauri/gen/android/app/.gitignore vendored Normal file
View file

@ -0,0 +1,6 @@
/src/main/java/net/unstoppableswap/gui/generated
/src/main/jniLibs/**/*.so
/src/main/assets/tauri.conf.json
/tauri.build.gradle.kts
/proguard-tauri.pro
/tauri.properties

View file

@ -0,0 +1,70 @@
import java.util.Properties
plugins {
id("com.android.application")
id("org.jetbrains.kotlin.android")
id("rust")
}
val tauriProperties = Properties().apply {
val propFile = file("tauri.properties")
if (propFile.exists()) {
propFile.inputStream().use { load(it) }
}
}
android {
compileSdk = 36
namespace = "net.unstoppableswap.gui"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "false"
applicationId = "net.unstoppableswap.gui"
minSdk = 24
targetSdk = 36
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
buildTypes {
getByName("debug") {
manifestPlaceholders["usesCleartextTraffic"] = "true"
isDebuggable = true
isJniDebuggable = true
isMinifyEnabled = false
packaging { jniLibs.keepDebugSymbols.add("*/arm64-v8a/*.so")
jniLibs.keepDebugSymbols.add("*/armeabi-v7a/*.so")
jniLibs.keepDebugSymbols.add("*/x86/*.so")
jniLibs.keepDebugSymbols.add("*/x86_64/*.so")
}
}
getByName("release") {
isMinifyEnabled = true
proguardFiles(
*fileTree(".") { include("**/*.pro") }
.plus(getDefaultProguardFile("proguard-android-optimize.txt"))
.toList().toTypedArray()
)
}
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
buildConfig = true
}
}
rust {
rootDirRel = "../../../"
}
dependencies {
implementation("androidx.webkit:webkit:1.14.0")
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("androidx.activity:activity-ktx:1.10.1")
implementation("com.google.android.material:material:1.12.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
}
apply(from = "tauri.build.gradle.kts")

View file

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View file

@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<!-- AndroidTV support -->
<uses-feature android:name="android.software.leanback" android:required="false" />
<application
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.unstoppableswap_gui_rs"
android:usesCleartextTraffic="${usesCleartextTraffic}">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode"
android:launchMode="singleTask"
android:label="@string/main_activity_title"
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<!-- AndroidTV support -->
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>

View file

@ -0,0 +1,11 @@
package net.unstoppableswap.gui
import android.os.Bundle
import androidx.activity.enableEdgeToEdge
class MainActivity : TauriActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
}
}

View file

@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeWidth="1"
android:strokeColor="#00000000" />
</vector>

View file

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#3DDC84"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeWidth="0.8"
android:strokeColor="#33FFFFFF" />
</vector>

View file

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

View file

@ -0,0 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.unstoppableswap_gui_rs" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
</resources>

View file

@ -0,0 +1,4 @@
<resources>
<string name="app_name">eigenwallet</string>
<string name="main_activity_title">eigenwallet</string>
</resources>

View file

@ -0,0 +1,6 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.unstoppableswap_gui_rs" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="my_images" path="." />
<cache-path name="my_cache_images" path="." />
</paths>

View file

@ -0,0 +1,22 @@
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath("com.android.tools.build:gradle:8.11.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25")
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
tasks.register("clean").configure {
delete("build")
}

View file

@ -0,0 +1,23 @@
plugins {
`kotlin-dsl`
}
gradlePlugin {
plugins {
create("pluginsForCoolKids") {
id = "rust"
implementationClass = "RustPlugin"
}
}
}
repositories {
google()
mavenCentral()
}
dependencies {
compileOnly(gradleApi())
implementation("com.android.tools.build:gradle:8.11.0")
}

View file

@ -0,0 +1,52 @@
import java.io.File
import org.apache.tools.ant.taskdefs.condition.Os
import org.gradle.api.DefaultTask
import org.gradle.api.GradleException
import org.gradle.api.logging.LogLevel
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.TaskAction
open class BuildTask : DefaultTask() {
@Input
var rootDirRel: String? = null
@Input
var target: String? = null
@Input
var release: Boolean? = null
@TaskAction
fun assemble() {
val executable = """cargo""";
try {
runTauriCli(executable)
} catch (e: Exception) {
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
runTauriCli("$executable.cmd")
} else {
throw e;
}
}
}
fun runTauriCli(executable: String) {
val rootDirRel = rootDirRel ?: throw GradleException("rootDirRel cannot be null")
val target = target ?: throw GradleException("target cannot be null")
val release = release ?: throw GradleException("release cannot be null")
val args = listOf("tauri", "android", "android-studio-script");
project.exec {
workingDir(File(project.projectDir, rootDirRel))
executable(executable)
args(args)
if (project.logger.isEnabled(LogLevel.DEBUG)) {
args("-vv")
} else if (project.logger.isEnabled(LogLevel.INFO)) {
args("-v")
}
if (release) {
args("--release")
}
args(listOf("--target", target))
}.assertNormalExitValue()
}
}

View file

@ -0,0 +1,85 @@
import com.android.build.api.dsl.ApplicationExtension
import org.gradle.api.DefaultTask
import org.gradle.api.Plugin
import org.gradle.api.Project
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.get
const val TASK_GROUP = "rust"
open class Config {
lateinit var rootDirRel: String
}
open class RustPlugin : Plugin<Project> {
private lateinit var config: Config
override fun apply(project: Project) = with(project) {
config = extensions.create("rust", Config::class.java)
val defaultAbiList = listOf("arm64-v8a", "armeabi-v7a", "x86", "x86_64");
val abiList = (findProperty("abiList") as? String)?.split(',') ?: defaultAbiList
val defaultArchList = listOf("arm64", "arm", "x86", "x86_64");
val archList = (findProperty("archList") as? String)?.split(',') ?: defaultArchList
val targetsList = (findProperty("targetList") as? String)?.split(',') ?: listOf("aarch64", "armv7", "i686", "x86_64")
extensions.configure<ApplicationExtension> {
@Suppress("UnstableApiUsage")
flavorDimensions.add("abi")
productFlavors {
create("universal") {
dimension = "abi"
ndk {
abiFilters += abiList
}
}
defaultArchList.forEachIndexed { index, arch ->
create(arch) {
dimension = "abi"
ndk {
abiFilters.add(defaultAbiList[index])
}
}
}
}
}
afterEvaluate {
for (profile in listOf("debug", "release")) {
val profileCapitalized = profile.replaceFirstChar { it.uppercase() }
val buildTask = tasks.maybeCreate(
"rustBuildUniversal$profileCapitalized",
DefaultTask::class.java
).apply {
group = TASK_GROUP
description = "Build dynamic library in $profile mode for all targets"
}
tasks["mergeUniversal${profileCapitalized}JniLibFolders"].dependsOn(buildTask)
for (targetPair in targetsList.withIndex()) {
val targetName = targetPair.value
val targetArch = archList[targetPair.index]
val targetArchCapitalized = targetArch.replaceFirstChar { it.uppercase() }
val targetBuildTask = project.tasks.maybeCreate(
"rustBuild$targetArchCapitalized$profileCapitalized",
BuildTask::class.java
).apply {
group = TASK_GROUP
description = "Build dynamic library in $profile mode for $targetArch"
rootDirRel = config.rootDirRel
target = targetName
release = profile == "release"
}
buildTask.dependsOn(targetBuildTask)
tasks["merge$targetArchCapitalized${profileCapitalized}JniLibFolders"].dependsOn(
targetBuildTask
)
}
}
}
}
}

View file

@ -0,0 +1,24 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
# https://developer.android.com/topic/libraries/support-library/androidx-rn
android.useAndroidX=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonFinalResIds=false

Binary file not shown.

View file

@ -0,0 +1,6 @@
#Tue May 10 19:22:52 CST 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

185
src-tauri/gen/android/gradlew vendored Executable file
View file

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
src-tauri/gen/android/gradlew.bat vendored Normal file
View file

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View file

@ -0,0 +1,3 @@
include ':app'
apply from: 'tauri.settings.gradle'

3
src-tauri/gen/apple/.gitignore vendored Normal file
View file

@ -0,0 +1,3 @@
xcuserdata/
build/
Externals/

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,116 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "AppIcon-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "AppIcon-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29x29@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "AppIcon-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "AppIcon-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "AppIcon-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "AppIcon-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "AppIcon-20x20@2x-1.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "AppIcon-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "AppIcon-40x40@2x-1.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "AppIcon-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "AppIcon-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "AppIcon-512@2x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View file

@ -0,0 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
}
}

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>method</key>
<string>debugging</string>
</dict>
</plist>

View file

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17150" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17122"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View file

@ -0,0 +1,21 @@
# Uncomment the next line to define a global platform for your project
target 'unstoppableswap-gui-rs_iOS' do
platform :ios, '13.0'
# Pods for unstoppableswap-gui-rs_iOS
end
target 'unstoppableswap-gui-rs_macOS' do
platform :osx, '11.0'
# Pods for unstoppableswap-gui-rs_macOS
end
# Delete the deployment target for iOS and macOS, causing it to be inherited from the Podfile
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
config.build_settings.delete 'MACOSX_DEPLOYMENT_TARGET'
end
end
end

View file

@ -0,0 +1,8 @@
#pragma once
namespace ffi {
extern "C" {
void start_app();
}
}

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