summaryrefslogtreecommitdiff
path: root/impls
diff options
context:
space:
mode:
Diffstat (limited to 'impls')
-rw-r--r--impls/monero.rs/.gitignore3
-rw-r--r--impls/monero.rs/Cargo.lock436
-rw-r--r--impls/monero.rs/Cargo.toml21
-rw-r--r--impls/monero.rs/README.md35
-rw-r--r--impls/monero.rs/build.rs136
-rw-r--r--impls/monero.rs/example/Cargo.lock295
-rw-r--r--impls/monero.rs/example/Cargo.toml7
-rw-r--r--impls/monero.rs/example/README.md30
-rw-r--r--impls/monero.rs/example/src/main.rs26
-rwxr-xr-ximpls/monero.rs/scripts/build_monero_c.sh68
-rw-r--r--impls/monero.rs/src/bindings.rs1621
-rw-r--r--impls/monero.rs/src/lib.rs450
-rw-r--r--impls/monero.rs/tests/integration_tests.rs256
13 files changed, 3384 insertions, 0 deletions
diff --git a/impls/monero.rs/.gitignore b/impls/monero.rs/.gitignore
new file mode 100644
index 0000000..e5eea29
--- /dev/null
+++ b/impls/monero.rs/.gitignore
@@ -0,0 +1,3 @@
+target/
+scripts/monero_c
+lib/
diff --git a/impls/monero.rs/Cargo.lock b/impls/monero.rs/Cargo.lock
new file mode 100644
index 0000000..9991a45
--- /dev/null
+++ b/impls/monero.rs/Cargo.lock
@@ -0,0 +1,436 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "anstyle"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1"
+
+[[package]]
+name = "bindgen"
+version = "0.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "itertools",
+ "log",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn",
+]
+
+[[package]]
+name = "bitflags"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clang-sys"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "downcast"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1435fa1053d8b2fbbe9be7e97eca7f33d37b28409959813daefc1446a14247f1"
+
+[[package]]
+name = "either"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+
+[[package]]
+name = "errno"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+dependencies = [
+ "libc",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6"
+
+[[package]]
+name = "fragile"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c2141d6d6c8512188a7891b4b01590a45f6dac67afb4f255c4124dbb86d4eaa"
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.159"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+
+[[package]]
+name = "libloading"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
+dependencies = [
+ "cfg-if",
+ "windows-targets",
+]
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+
+[[package]]
+name = "log"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "mockall"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d4c28b3fb6d753d28c20e826cd46ee611fda1cf3cde03a443a974043247c065a"
+dependencies = [
+ "cfg-if",
+ "downcast",
+ "fragile",
+ "mockall_derive",
+ "predicates",
+ "predicates-tree",
+]
+
+[[package]]
+name = "mockall_derive"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "341014e7f530314e9a1fdbc7400b244efea7122662c96bfa248c31da5bfb2020"
+dependencies = [
+ "cfg-if",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "monero_c_rust"
+version = "0.0.1"
+dependencies = [
+ "bindgen",
+ "mockall",
+ "tempfile",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.20.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
+
+[[package]]
+name = "predicates"
+version = "3.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7e9086cc7640c29a356d1a29fd134380bee9d8f79a17410aa76e7ad295f42c97"
+dependencies = [
+ "anstyle",
+ "predicates-core",
+]
+
+[[package]]
+name = "predicates-core"
+version = "1.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ae8177bee8e75d6846599c6b9ff679ed51e882816914eec639944d7c9aa11931"
+
+[[package]]
+name = "predicates-tree"
+version = "1.0.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "41b740d195ed3166cd147c8047ec98db0e22ec019eb8eeb76d343b795304fb13"
+dependencies = [
+ "predicates-core",
+ "termtree",
+]
+
+[[package]]
+name = "prettyplease"
+version = "0.2.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "rustix"
+version = "0.38.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8acb788b847c24f28525660c4d7758620a7210875711f79e7f663cc152726811"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "syn"
+version = "2.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "tempfile"
+version = "3.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "once_cell",
+ "rustix",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "termtree"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.59.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/impls/monero.rs/Cargo.toml b/impls/monero.rs/Cargo.toml
new file mode 100644
index 0000000..f055225
--- /dev/null
+++ b/impls/monero.rs/Cargo.toml
@@ -0,0 +1,21 @@
+[package]
+name = "monero_c_rust"
+version = "0.0.1"
+edition = "2021"
+description = "monero_c Rust bindings."
+repository = "https://github.com/MrCyjaneK/monero_c"
+license = "MIT"
+build = "build.rs"
+
+[lib]
+name = "monero_c_rust"
+path = "src/lib.rs"
+crate-type = ["lib", "cdylib"]
+
+[dependencies]
+mockall = "0.13.0"
+tempfile = "3.13.0"
+
+[build-dependencies]
+bindgen = "0.70.1"
+
diff --git a/impls/monero.rs/README.md b/impls/monero.rs/README.md
new file mode 100644
index 0000000..e8dc15c
--- /dev/null
+++ b/impls/monero.rs/README.md
@@ -0,0 +1,35 @@
+# `monero_rust`
+Proof of concept `monero_c` bindings for Rust.
+
+## Getting started
+<!--
+### Prerequisites
+You may need
+```
+sudo apt-get install libhidapi-dev
+```
+-->
+### Build or download `monero_c` library
+Build or download the `monero_c` library for your architecture. Follow the
+upstream docs at https://github.com/MrCyjaneK/monero_c or download the latest
+release from https://github.com/MrCyjaneK/monero_c/releases. The library can be
+placed in one of several supported locations relative to the binary in use:
+- `../../../../release` (as in `monero_c/release`)
+- `../../lib` (as in `monero_c/impls/monero_rust/lib`)
+- `.` (as in `monero_c/impls/monero_rust/target/debug` or `release`)
+
+and should match your platform as in:
+- Android: `libmonero_libwallet2_api_c.so`
+- iOS: `MoneroWallet.framework/MoneroWallet`
+- Linux: `monero_libwallet2_api_c.so`
+- macOS: `monero_libwallet2_api_c.dylib`
+- Windows: `monero_libwallet2_api_c.dll`
+
+### Run demo
+With the library in a supported location, from `monero_c/impls/monero_rust`:
+```
+cargo run
+```
+
+## Using `monero_rust` in your own crate
+Refer to the `example` folder. Library placement is the same as for the demo.
diff --git a/impls/monero.rs/build.rs b/impls/monero.rs/build.rs
new file mode 100644
index 0000000..3fe2f81
--- /dev/null
+++ b/impls/monero.rs/build.rs
@@ -0,0 +1,136 @@
+use std::env;
+use std::fs::{self, OpenOptions};
+use std::io::Write;
+use std::path::PathBuf;
+use bindgen::EnumVariation;
+
+#[cfg(unix)]
+use std::os::unix::fs as unix_fs;
+
+#[cfg(target_os = "windows")]
+use std::fs::copy;
+
+fn main() {
+ let header_path = "../../monero_libwallet2_api_c/src/main/cpp/wallet2_api_c.h";
+ let lib_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("../../release");
+
+ // Set library names based on target OS.
+ //
+ // This rigamarole is currently required because the "monero_libwallet2_api_c" library is also
+ // required under the names "wallet2_api_c" and "libmonero_libwallet2_api_c" by various parts of
+ // the stack. This is a temporary workaround until the library is refactored to use a single
+ // name consistently.
+ let original_lib = if cfg!(target_os = "windows") {
+ lib_path.join("monero_libwallet2_api_c.dll")
+ } else if cfg!(target_os = "macos") {
+ lib_path.join("monero_libwallet2_api_c.dylib")
+ } else {
+ lib_path.join("monero_libwallet2_api_c.so")
+ };
+
+ let symlink_1 = if cfg!(target_os = "windows") {
+ lib_path.join("wallet2_api_c.dll")
+ } else if cfg!(target_os = "macos") {
+ lib_path.join("libwallet2_api_c.dylib")
+ } else {
+ lib_path.join("libwallet2_api_c.so")
+ };
+
+ let symlink_2 = if cfg!(target_os = "windows") {
+ lib_path.join("monero_wallet2_api_c.dll")
+ } else if cfg!(target_os = "macos") {
+ lib_path.join("libmonero_libwallet2_api_c.dylib")
+ } else {
+ lib_path.join("libmonero_libwallet2_api_c.so")
+ };
+
+ // On Unix-like systems, create symlinks.
+ #[cfg(unix)]
+ {
+ if original_lib.exists() && !symlink_1.exists() {
+ unix_fs::symlink(&original_lib, &symlink_1)
+ .expect("Failed to create symbolic link for libwallet2_api_c.so");
+ }
+
+ if original_lib.exists() && !symlink_2.exists() {
+ unix_fs::symlink(&original_lib, &symlink_2)
+ .expect("Failed to create symbolic link for libmonero_libwallet2_api_c.so");
+ }
+ }
+
+ // On Windows, copy the files instead of symlinking.
+ #[cfg(target_os = "windows")]
+ {
+ if original_lib.exists() && !symlink_1.exists() {
+ copy(&original_lib, &symlink_1).expect("Failed to copy DLL file to wallet2_api_c.dll");
+ }
+
+ if original_lib.exists() && !symlink_2.exists() {
+ copy(&original_lib, &symlink_2)
+ .expect("Failed to copy DLL file to monero_wallet2_api_c.dll");
+ }
+ }
+
+ println!("cargo:rerun-if-changed={}", header_path);
+ println!("cargo:rerun-if-changed=build.rs");
+
+ println!("cargo:rustc-link-search=native={}", lib_path.display());
+ println!("cargo:rustc-link-lib=dylib=monero_libwallet2_api_c");
+ println!("cargo:rustc-link-lib=dylib=stdc++");
+ println!("cargo:rustc-link-lib=dylib=hidapi-hidraw");
+ println!("cargo:rustc-link-arg=-Wl,-rpath,{}", lib_path.display());
+
+ // Generate bindings using bindgen.
+ let bindings = bindgen::Builder::default()
+ .header(header_path)
+ .allowlist_function("MONERO_.*")
+ .allowlist_var("MONERO_.*")
+ .allowlist_var("NetworkType_.*")
+ .allowlist_var("PendingTransactionStatus_.*")
+ .allowlist_var("Priority_.*")
+ .allowlist_var("UnsignedTransactionStatus_.*")
+ .allowlist_var("TransactionInfoDirection_.*")
+ .allowlist_var("AddressBookErrorCode.*")
+ .allowlist_var("WalletDevice_.*")
+ .allowlist_var("WalletStatus_.*")
+ .allowlist_var("WalletConnectionStatus_.*")
+ .allowlist_var("WalletBackgroundSync_.*")
+ .allowlist_var("BackgroundSync_.*")
+ .allowlist_var("LogLevel_.*")
+ .blocklist_type("__.*")
+ .blocklist_type("_.*")
+ .blocklist_function("__.*")
+ .layout_tests(false)
+ .default_enum_style(EnumVariation::Rust { non_exhaustive: false })
+ .derive_default(false)
+ .conservative_inline_namespaces()
+ .generate_comments(false)
+ .generate()
+ .expect("Unable to generate bindings");
+
+ let out_path = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap())
+ .join("src")
+ .join("bindings.rs");
+ bindings
+ .write_to_file(out_path.clone())
+ .expect("Couldn't write bindings!");
+
+ // Annotate the generated bindings to ignore certain warnings.
+ if out_path.exists() {
+ let contents = fs::read_to_string(out_path.clone()).expect("Failed to read bindings.rs");
+
+ let prepend_content = "#![allow(non_upper_case_globals)]\n#![allow(dead_code)]\n";
+
+ if !contents.contains("#![allow(non_upper_case_globals)]") {
+ let new_contents = format!("{}{}", prepend_content, contents);
+
+ let mut file = OpenOptions::new()
+ .write(true)
+ .truncate(true)
+ .open(out_path.clone())
+ .expect("Failed to open bindings.rs");
+
+ file.write_all(new_contents.as_bytes()).expect("Failed to write to bindings.rs");
+ }
+ }
+}
diff --git a/impls/monero.rs/example/Cargo.lock b/impls/monero.rs/example/Cargo.lock
new file mode 100644
index 0000000..d921e0d
--- /dev/null
+++ b/impls/monero.rs/example/Cargo.lock
@@ -0,0 +1,295 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "bindgen"
+version = "0.70.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f49d8fed880d473ea71efb9bf597651e77201bdd4893efe54c9e5d65ae04ce6f"
+dependencies = [
+ "bitflags",
+ "cexpr",
+ "clang-sys",
+ "itertools",
+ "log",
+ "prettyplease",
+ "proc-macro2",
+ "quote",
+ "regex",
+ "rustc-hash",
+ "shlex",
+ "syn",
+]
+
+[[package]]
+name = "bitflags"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+[[package]]
+name = "cexpr"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
+dependencies = [
+ "nom",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clang-sys"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
+dependencies = [
+ "glob",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "either"
+version = "1.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
+
+[[package]]
+name = "glob"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
+
+[[package]]
+name = "itertools"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "libc"
+version = "0.2.159"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5"
+
+[[package]]
+name = "libloading"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
+dependencies = [
+ "cfg-if",
+ "windows-targets",
+]
+
+[[package]]
+name = "log"
+version = "0.4.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "minimal-lexical"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
+
+[[package]]
+name = "monero_example"
+version = "0.0.1"
+dependencies = [
+ "monero_rust",
+]
+
+[[package]]
+name = "monero_rust"
+version = "0.0.1"
+dependencies = [
+ "bindgen",
+ "libc",
+ "libloading",
+]
+
+[[package]]
+name = "nom"
+version = "7.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
+dependencies = [
+ "memchr",
+ "minimal-lexical",
+]
+
+[[package]]
+name = "prettyplease"
+version = "0.2.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba"
+dependencies = [
+ "proc-macro2",
+ "syn",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.87"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a"
+dependencies = [
+ "unicode-ident",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.37"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "regex"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
+
+[[package]]
+name = "rustc-hash"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
+
+[[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
+name = "syn"
+version = "2.0.79"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-ident",
+]
+
+[[package]]
+name = "unicode-ident"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
+
+[[package]]
+name = "windows-targets"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
+dependencies = [
+ "windows_aarch64_gnullvm",
+ "windows_aarch64_msvc",
+ "windows_i686_gnu",
+ "windows_i686_gnullvm",
+ "windows_i686_msvc",
+ "windows_x86_64_gnu",
+ "windows_x86_64_gnullvm",
+ "windows_x86_64_msvc",
+]
+
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
+
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
+
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
+
+[[package]]
+name = "windows_i686_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
+
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
+
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
+
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
+
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
diff --git a/impls/monero.rs/example/Cargo.toml b/impls/monero.rs/example/Cargo.toml
new file mode 100644
index 0000000..e0b7823
--- /dev/null
+++ b/impls/monero.rs/example/Cargo.toml
@@ -0,0 +1,7 @@
+[package]
+name = "monero_example"
+version = "0.0.1"
+edition = "2021"
+
+[dependencies]
+monero_rust = { path = ".." }
diff --git a/impls/monero.rs/example/README.md b/impls/monero.rs/example/README.md
new file mode 100644
index 0000000..3b6ba4c
--- /dev/null
+++ b/impls/monero.rs/example/README.md
@@ -0,0 +1,30 @@
+# `monero_c/impls/monero.rs/example`
+Refer to the latest documentation at
+https://github.com/MrCyjaneK/monero_c/blob/master/README.md and
+https://github.com/MrCyjaneK/monero_c/blob/master/impls/monero.rs/README.md for
+the latest documentation.
+
+## `monero_c` library
+A `monero_c` library is required to use these bindings. Build or download the
+`monero_c` library for your architecture. Follow the upstream docs at
+https://github.com/MrCyjaneK/monero_c or download the latest release from
+https://github.com/MrCyjaneK/monero_c/releases. The library can be placed in
+one of several supported locations relative to the binary in use:
+- `.`
+ that is, if your binary is in `target/debug` or `target/release`, the library
+ should also be adjacent to the binary in `release` or `debug`, respectively.
+ If you're distributing your binary, place the library in the same directory.
+- `../../lib`
+ so if your binary gets built to `target/profile`, then your library can be
+ in `lib`.
+- `../../../../release`
+ which is a holdover from the original `monero_c` bindings and may not be
+ practical for your project unless it's also structured as a child of the
+ `monero_c` repository.
+
+and should match your platform as in:
+- Android: `libmonero_libwallet2_api_c.so`
+- iOS: `MoneroWallet.framework/MoneroWallet`
+- Linux: `monero_libwallet2_api_c.so`
+- macOS: `monero_libwallet2_api_c.dylib`
+- Windows: `monero_libwallet2_api_c.dll`
diff --git a/impls/monero.rs/example/src/main.rs b/impls/monero.rs/example/src/main.rs
new file mode 100644
index 0000000..099c6d4
--- /dev/null
+++ b/impls/monero.rs/example/src/main.rs
@@ -0,0 +1,26 @@
+use monero_rust::{network, WalletError, WalletManager};
+
+fn main() -> Result<(), WalletError> {
+ let wallet_manager = WalletManager::new(None)?;
+
+ let wallet = wallet_manager.create_wallet(
+ "wallet_name",
+ "password",
+ "English",
+ network::MAINNET,
+ )?;
+
+ println!("Wallet created successfully.");
+
+ match wallet.get_seed("") {
+ Ok(seed) => println!("Seed: {}", seed),
+ Err(e) => eprintln!("Failed to get seed: {:?}", e),
+ }
+
+ match wallet.get_address(0, 0) {
+ Ok(address) => println!("Primary address: {}", address),
+ Err(e) => eprintln!("Failed to get address: {:?}", e),
+ }
+
+ Ok(())
+}
diff --git a/impls/monero.rs/scripts/build_monero_c.sh b/impls/monero.rs/scripts/build_monero_c.sh
new file mode 100755
index 0000000..ca9fba4
--- /dev/null
+++ b/impls/monero.rs/scripts/build_monero_c.sh
@@ -0,0 +1,68 @@
+#!/bin/bash
+
+set -x -e
+
+# See https://github.com/MrCyjaneK/monero_c for the most up-to-date build docs,
+# this is an example and a starting point for building monero_c for use in Rust
+# but it should be automated either using CMake or Cargo (preferred).
+
+# Detect architecture.
+ARCH=$(uname -m)
+OS=$(uname -s)
+
+case $ARCH-$OS in
+ x86_64-Linux)
+ TARGET_ARCH="x86_64-linux-gnu"
+ ;;
+ i686-Linux)
+ TARGET_ARCH="i686-linux-gnu"
+ ;;
+ aarch64-Linux)
+ TARGET_ARCH="aarch64-linux-gnu"
+ ;;
+ x86_64-Android)
+ TARGET_ARCH="x86_64-linux-android"
+ ;;
+ i686-Android)
+ TARGET_ARCH="i686-linux-android"
+ ;;
+ aarch64-Android)
+ TARGET_ARCH="aarch64-linux-android"
+ ;;
+ armv7l-Android)
+ TARGET_ARCH="arm-linux-androideabi"
+ ;;
+ i686-Windows)
+ TARGET_ARCH="i686-w64-mingw32"
+ ;;
+ x86_64-Windows)
+ TARGET_ARCH="x86_64-w64-mingw32"
+ ;;
+ x86_64-Darwin)
+ TARGET_ARCH="host-apple-darwin"
+ ;;
+ arm64-Darwin)
+ TARGET_ARCH="host-apple-ios"
+ ;;
+ *)
+ echo "Unsupported architecture: $ARCH on OS: $OS"
+ exit 1
+ ;;
+esac
+
+
+unxz -f release/monero/${TARGET_ARCH}_libwallet2_api_c.so.xz
+#unxz -f release/wownero/${TARGET_ARCH}_libwallet2_api_c.so.xz
+
+# Navigate back to /scripts.
+cd ..
+
+# Copy the built .so file to a generic name.
+SO_FILE="monero_c/release/monero/${TARGET_ARCH}_libwallet2_api_c.so"
+if [[ -f "$SO_FILE" ]]; then
+ cp "$SO_FILE" "../lib/libwallet2_api_c.so"
+ echo "Copied $SO_FILE to libwallet2_api_c.so"
+else
+ echo "Error: $SO_FILE not found."
+ exit 1
+fi
diff --git a/impls/monero.rs/src/bindings.rs b/impls/monero.rs/src/bindings.rs
new file mode 100644
index 0000000..556f5ad
--- /dev/null
+++ b/impls/monero.rs/src/bindings.rs
@@ -0,0 +1,1621 @@
+#![allow(non_upper_case_globals)]
+#![allow(dead_code)]
+/* automatically generated by rust-bindgen 0.70.1 */
+
+pub const MONERO_wallet2_api_c_h_sha256: &[u8; 65] =
+ b"e8db0ef0324a153f5e3ecca4c0db23c54f4576e84988f04bd4f11c1142f9d7ad\0";
+pub const MONERO_wallet2_api_c_cpp_sha256 : & [u8 ; 106] = b"dca52ac9ee009fda9fb5726543a454885e61d8eb74fb33112288029ed625bec5-b089f9ee69924882c5d14dd1a6991deb05d9d1cd\0" ;
+pub const MONERO_wallet2_api_c_exp_sha256: &[u8; 65] =
+ b"c8913ac41068f67b57c9b0a3c7dd8973e3c1273b66c2ff0aadb0003931da748c\0";
+pub const NetworkType_MAINNET: ::std::os::raw::c_int = 0;
+pub const NetworkType_TESTNET: ::std::os::raw::c_int = 1;
+pub const NetworkType_STAGENET: ::std::os::raw::c_int = 2;
+pub const PendingTransactionStatus_Ok: ::std::os::raw::c_int = 0;
+pub const PendingTransactionStatus_Error: ::std::os::raw::c_int = 1;
+pub const PendingTransactionStatus_Critical: ::std::os::raw::c_int = 2;
+pub const Priority_Default: ::std::os::raw::c_int = 0;
+pub const Priority_Low: ::std::os::raw::c_int = 1;
+pub const Priority_Medium: ::std::os::raw::c_int = 2;
+pub const Priority_High: ::std::os::raw::c_int = 3;
+pub const Priority_Last: ::std::os::raw::c_int = 4;
+extern "C" {
+ pub fn MONERO_PendingTransaction_status(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_errorString(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_commit(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ filename: *const ::std::os::raw::c_char,
+ overwrite: bool,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_commitUR(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ max_fragment_length: ::std::os::raw::c_int,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_amount(pendingTx_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_dust(pendingTx_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_fee(pendingTx_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_txid(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_txCount(pendingTx_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_subaddrAccount(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_subaddrIndices(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_multisigSignData(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_signMultisigTx(pendingTx_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_signersKeys(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_PendingTransaction_hex(
+ pendingTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+pub const UnsignedTransactionStatus_Ok: ::std::os::raw::c_int = 0;
+pub const UnsignedTransactionStatus_Error: ::std::os::raw::c_int = 1;
+pub const UnsignedTransactionStatus_Critical: ::std::os::raw::c_int = 2;
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_status(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_errorString(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_amount(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_fee(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_mixin(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_confirmationMessage(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_paymentId(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_recipientAddress(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_minMixinCount(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_txCount(unsignedTx_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_sign(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ signedFileName: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_UnsignedTransaction_signUR(
+ unsignedTx_ptr: *mut ::std::os::raw::c_void,
+ max_fragment_length: ::std::os::raw::c_int,
+ ) -> *const ::std::os::raw::c_char;
+}
+pub const TransactionInfoDirection_In: ::std::os::raw::c_int = 0;
+pub const TransactionInfoDirection_Out: ::std::os::raw::c_int = 1;
+extern "C" {
+ pub fn MONERO_TransactionInfo_direction(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_isPending(txInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_isFailed(txInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_isCoinbase(txInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_amount(txInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_fee(txInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_blockHeight(txInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_description(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_subaddrIndex(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_subaddrAccount(txInfo_ptr: *mut ::std::os::raw::c_void) -> u32;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_label(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_confirmations(txInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_unlockTime(txInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_hash(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_timestamp(txInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_paymentId(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_transfers_count(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_transfers_amount(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_TransactionInfo_transfers_address(
+ txInfo_ptr: *mut ::std::os::raw::c_void,
+ address: ::std::os::raw::c_int,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_TransactionHistory_count(
+ txHistory_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_TransactionHistory_transaction(
+ txHistory_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_TransactionHistory_transactionById(
+ txHistory_ptr: *mut ::std::os::raw::c_void,
+ id: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_TransactionHistory_refresh(txHistory_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_TransactionHistory_setTxNote(
+ txHistory_ptr: *mut ::std::os::raw::c_void,
+ txid: *const ::std::os::raw::c_char,
+ note: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_AddressBookRow_extra(
+ addressBookRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_AddressBookRow_getAddress(
+ addressBookRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_AddressBookRow_getDescription(
+ addressBookRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_AddressBookRow_getPaymentId(
+ addressBookRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_AddressBookRow_getRowId(addressBookRow_ptr: *mut ::std::os::raw::c_void)
+ -> usize;
+}
+pub const AddressBookErrorCodeStatus_Ok: ::std::os::raw::c_int = 0;
+pub const AddressBookErrorCodeGeneral_Error: ::std::os::raw::c_int = 1;
+pub const AddressBookErrorCodeInvalid_Address: ::std::os::raw::c_int = 2;
+pub const AddressBookErrorCodeInvalidPaymentId: ::std::os::raw::c_int = 3;
+extern "C" {
+ pub fn MONERO_AddressBook_getAll_size(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_getAll_byIndex(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_addRow(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ dst_addr: *const ::std::os::raw::c_char,
+ payment_id: *const ::std::os::raw::c_char,
+ description: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_deleteRow(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ rowId: usize,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_setDescription(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ rowId: usize,
+ description: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_refresh(addressBook_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_AddressBook_errorString(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_errorCode(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_AddressBook_lookupPaymentID(
+ addressBook_ptr: *mut ::std::os::raw::c_void,
+ payment_id: *const ::std::os::raw::c_char,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_blockHeight(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_hash(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_internalOutputIndex(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> usize;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_globalOutputIndex(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_spent(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_frozen(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_spentHeight(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_amount(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_rct(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_keyImageKnown(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_pkIndex(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> usize;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_subaddrIndex(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u32;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_subaddrAccount(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u32;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_address(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_addressLabel(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_keyImage(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_unlockTime(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_unlocked(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_pubKey(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_coinbase(coinsInfo_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_CoinsInfo_description(
+ coinsInfo_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Coins_count(coins_ptr: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Coins_coin(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Coins_getAll_size(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Coins_getAll_byIndex(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Coins_refresh(coins_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_Coins_setFrozenByPublicKey(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ public_key: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Coins_setFrozen(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ );
+}
+extern "C" {
+ pub fn MONERO_Coins_thaw(coins_ptr: *mut ::std::os::raw::c_void, index: ::std::os::raw::c_int);
+}
+extern "C" {
+ pub fn MONERO_Coins_thawByPublicKey(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ public_key: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Coins_isTransferUnlocked(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ unlockTime: u64,
+ blockHeight: u64,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Coins_setDescription(
+ coins_ptr: *mut ::std::os::raw::c_void,
+ public_key: *const ::std::os::raw::c_char,
+ description: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_SubaddressRow_extra(
+ subaddressRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressRow_getAddress(
+ subaddressRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressRow_getLabel(
+ subaddressRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressRow_getRowId(subaddressRow_ptr: *mut ::std::os::raw::c_void) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Subaddress_getAll_size(
+ subaddress_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Subaddress_getAll_byIndex(
+ subaddress_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Subaddress_addRow(
+ subaddress_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Subaddress_setLabel(
+ subaddress_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ addressIndex: u32,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Subaddress_refresh(
+ subaddress_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ );
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccountRow_extra(
+ subaddressAccountRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccountRow_getAddress(
+ subaddressAccountRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccountRow_getLabel(
+ subaddressAccountRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccountRow_getBalance(
+ subaddressAccountRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccountRow_getUnlockedBalance(
+ subaddressAccountRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccountRow_getRowId(
+ subaddressAccountRow_ptr: *mut ::std::os::raw::c_void,
+ ) -> usize;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccount_getAll_size(
+ subaddressAccount_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccount_getAll_byIndex(
+ subaddressAccount_ptr: *mut ::std::os::raw::c_void,
+ index: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccount_addRow(
+ subaddressAccount_ptr: *mut ::std::os::raw::c_void,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccount_setLabel(
+ subaddressAccount_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_SubaddressAccount_refresh(subaddressAccount_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_MultisigState_isMultisig(multisigState_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_MultisigState_isReady(multisigState_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_MultisigState_threshold(multisigState_ptr: *mut ::std::os::raw::c_void) -> u32;
+}
+extern "C" {
+ pub fn MONERO_MultisigState_total(multisigState_ptr: *mut ::std::os::raw::c_void) -> u32;
+}
+extern "C" {
+ pub fn MONERO_DeviceProgress_progress(deviceProgress_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_DeviceProgress_indeterminate(
+ deviceProgress_ptr: *mut ::std::os::raw::c_void,
+ ) -> bool;
+}
+pub const WalletDevice_Software: ::std::os::raw::c_int = 0;
+pub const WalletDevice_Ledger: ::std::os::raw::c_int = 1;
+pub const WalletDevice_Trezor: ::std::os::raw::c_int = 2;
+pub const WalletStatus_Ok: ::std::os::raw::c_int = 0;
+pub const WalletStatus_Error: ::std::os::raw::c_int = 1;
+pub const WalletStatus_Critical: ::std::os::raw::c_int = 2;
+pub const WalletConnectionStatus_Disconnected: ::std::os::raw::c_int = 0;
+pub const WalletConnectionStatus_Connected: ::std::os::raw::c_int = 1;
+pub const WalletConnectionStatus_WrongVersion: ::std::os::raw::c_int = 2;
+pub const WalletBackgroundSync_Off: ::std::os::raw::c_int = 0;
+pub const WalletBackgroundSync_ReusePassword: ::std::os::raw::c_int = 1;
+pub const BackgroundSync_CustomPassword: ::std::os::raw::c_int = 2;
+extern "C" {
+ pub fn MONERO_Wallet_seed(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ seed_offset: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getSeedLanguage(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setSeedLanguage(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ arg: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_status(wallet_ptr: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Wallet_errorString(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setPassword(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ password: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getPassword(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setDevicePin(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ pin: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setDevicePassphrase(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ passphrase: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_address(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u64,
+ addressIndex: u64,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_path(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_nettype(wallet_ptr: *mut ::std::os::raw::c_void) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Wallet_useForkRules(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ version: u8,
+ early_blocks: i64,
+ ) -> u8;
+}
+extern "C" {
+ pub fn MONERO_Wallet_integratedAddress(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ payment_id: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_secretViewKey(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_publicViewKey(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_secretSpendKey(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_publicSpendKey(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_publicMultisigSignerKey(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_stop(wallet_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_Wallet_store(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_filename(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_keysFilename(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_init(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ daemon_address: *const ::std::os::raw::c_char,
+ upper_transaction_size_limit: u64,
+ daemon_username: *const ::std::os::raw::c_char,
+ daemon_password: *const ::std::os::raw::c_char,
+ use_ssl: bool,
+ lightWallet: bool,
+ proxy_address: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_createWatchOnly(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ language: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setRefreshFromBlockHeight(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ refresh_from_block_height: u64,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_getRefreshFromBlockHeight(wallet_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setRecoveringFromSeed(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ recoveringFromSeed: bool,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_setRecoveringFromDevice(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ recoveringFromDevice: bool,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_setSubaddressLookahead(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ major: u32,
+ minor: u32,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_connectToDaemon(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_connected(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setTrustedDaemon(wallet_ptr: *mut ::std::os::raw::c_void, arg: bool);
+}
+extern "C" {
+ pub fn MONERO_Wallet_trustedDaemon(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setProxy(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ address: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_balance(wallet_ptr: *mut ::std::os::raw::c_void, accountIndex: u32)
+ -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_unlockedBalance(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_viewOnlyBalance(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_watchOnly(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_isDeterministic(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_blockChainHeight(wallet_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_approximateBlockChainHeight(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_estimateBlockChainHeight(wallet_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_daemonBlockChainHeight(wallet_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_daemonBlockChainHeight_cached(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_daemonBlockChainHeight_runThread(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ seconds: ::std::os::raw::c_int,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_daemonBlockChainTargetHeight(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_synchronized(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_displayAmount(amount: u64) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_amountFromString(amount: *const ::std::os::raw::c_char) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_amountFromDouble(amount: f64) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_genPaymentId() -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_paymentIdValid(paiment_id: *const ::std::os::raw::c_char) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_addressValid(
+ str_: *const ::std::os::raw::c_char,
+ nettype: ::std::os::raw::c_int,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_keyValid(
+ secret_key_string: *const ::std::os::raw::c_char,
+ address_string: *const ::std::os::raw::c_char,
+ isViewKey: bool,
+ nettype: ::std::os::raw::c_int,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_keyValid_error(
+ secret_key_string: *const ::std::os::raw::c_char,
+ address_string: *const ::std::os::raw::c_char,
+ isViewKey: bool,
+ nettype: ::std::os::raw::c_int,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_paymentIdFromAddress(
+ strarg: *const ::std::os::raw::c_char,
+ nettype: ::std::os::raw::c_int,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_maximumAllowedAmount() -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_init3(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ argv0: *const ::std::os::raw::c_char,
+ default_log_base_name: *const ::std::os::raw::c_char,
+ log_path: *const ::std::os::raw::c_char,
+ console: bool,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_getPolyseed(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ passphrase: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_createPolyseed(
+ language: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_startRefresh(wallet_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_Wallet_pauseRefresh(wallet_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_Wallet_refresh(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_refreshAsync(wallet_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_Wallet_rescanBlockchain(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_rescanBlockchainAsync(wallet_ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_Wallet_setAutoRefreshInterval(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ millis: ::std::os::raw::c_int,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_autoRefreshInterval(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Wallet_addSubaddressAccount(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_numSubaddressAccounts(wallet_ptr: *mut ::std::os::raw::c_void) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Wallet_numSubaddresses(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ ) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Wallet_addSubaddress(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_getSubaddressLabel(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ addressIndex: u32,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setSubaddressLabel(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ addressIndex: u32,
+ label: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_multisig(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getMultisigInfo(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_makeMultisig(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ info: *const ::std::os::raw::c_char,
+ info_separator: *const ::std::os::raw::c_char,
+ threshold: u32,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_exchangeMultisigKeys(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ info: *const ::std::os::raw::c_char,
+ info_separator: *const ::std::os::raw::c_char,
+ force_update_use_with_caution: bool,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_exportMultisigImages(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_importMultisigImages(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ info: *const ::std::os::raw::c_char,
+ info_separator: *const ::std::os::raw::c_char,
+ ) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Wallet_hasMultisigPartialKeyImages(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Wallet_restoreMultisigTransaction(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ signData: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_createTransactionMultDest(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ dst_addr_list: *const ::std::os::raw::c_char,
+ dst_addr_list_separator: *const ::std::os::raw::c_char,
+ payment_id: *const ::std::os::raw::c_char,
+ amount_sweep_all: bool,
+ amount_list: *const ::std::os::raw::c_char,
+ amount_list_separator: *const ::std::os::raw::c_char,
+ mixin_count: u32,
+ pendingTransactionPriority: ::std::os::raw::c_int,
+ subaddr_account: u32,
+ preferredInputs: *const ::std::os::raw::c_char,
+ preferredInputs_separator: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_createTransaction(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ dst_addr: *const ::std::os::raw::c_char,
+ payment_id: *const ::std::os::raw::c_char,
+ amount: u64,
+ mixin_count: u32,
+ pendingTransactionPriority: ::std::os::raw::c_int,
+ subaddr_account: u32,
+ preferredInputs: *const ::std::os::raw::c_char,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_loadUnsignedTx(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ unsigned_filename: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_loadUnsignedTxUR(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ input: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_submitTransaction(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ fileName: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_submitTransactionUR(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ input: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_hasUnknownKeyImages(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_exportKeyImages(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ filename: *const ::std::os::raw::c_char,
+ all: bool,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_exportKeyImagesUR(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ max_fragment_length: usize,
+ all: bool,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_importKeyImages(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ filename: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_importKeyImagesUR(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ input: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_exportOutputs(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ filename: *const ::std::os::raw::c_char,
+ all: bool,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_exportOutputsUR(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ max_fragment_length: usize,
+ all: bool,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_importOutputs(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ filename: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_importOutputsUR(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ input: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setupBackgroundSync(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ background_sync_type: ::std::os::raw::c_int,
+ wallet_password: *const ::std::os::raw::c_char,
+ background_cache_password: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getBackgroundSyncType(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Wallet_startBackgroundSync(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_stopBackgroundSync(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ wallet_password: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_isBackgroundSyncing(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_isBackgroundWallet(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_history(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_addressBook(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_coins(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_subaddress(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_subaddressAccount(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_Wallet_defaultMixin(wallet_ptr: *mut ::std::os::raw::c_void) -> u32;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setDefaultMixin(wallet_ptr: *mut ::std::os::raw::c_void, arg: u32);
+}
+extern "C" {
+ pub fn MONERO_Wallet_setCacheAttribute(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ key: *const ::std::os::raw::c_char,
+ val: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getCacheAttribute(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ key: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setUserNote(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ txid: *const ::std::os::raw::c_char,
+ note: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getUserNote(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ txid: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getTxKey(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ txid: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_signMessage(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ message: *const ::std::os::raw::c_char,
+ address: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_verifySignedMessage(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ message: *const ::std::os::raw::c_char,
+ address: *const ::std::os::raw::c_char,
+ signature: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_rescanSpent(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setOffline(wallet_ptr: *mut ::std::os::raw::c_void, offline: bool);
+}
+extern "C" {
+ pub fn MONERO_Wallet_isOffline(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_segregatePreForkOutputs(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ segregate: bool,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_segregationHeight(wallet_ptr: *mut ::std::os::raw::c_void, height: u64);
+}
+extern "C" {
+ pub fn MONERO_Wallet_keyReuseMitigation2(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ mitigation: bool,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_lockKeysFile(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_unlockKeysFile(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_isKeysFileLocked(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getDeviceType(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_Wallet_coldKeyImageSync(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ spent: u64,
+ unspent: u64,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_deviceShowAddress(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ accountIndex: u32,
+ addressIndex: u32,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_Wallet_reconnectDevice(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getBytesReceived(wallet_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getBytesSent(wallet_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getStateIsConnected(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getSendToDevice(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_uchar;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getSendToDeviceLength(wallet_ptr: *mut ::std::os::raw::c_void) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getReceivedFromDevice(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_uchar;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getReceivedFromDeviceLength(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> usize;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getWaitsForDeviceSend(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_getWaitsForDeviceReceive(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_Wallet_setDeviceReceivedData(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ data: *mut ::std::os::raw::c_uchar,
+ len: usize,
+ );
+}
+extern "C" {
+ pub fn MONERO_Wallet_setDeviceSendData(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ data: *mut ::std::os::raw::c_uchar,
+ len: usize,
+ );
+}
+extern "C" {
+ pub fn MONERO_WalletManager_createWallet(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ language: *const ::std::os::raw::c_char,
+ networkType: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_openWallet(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ networkType: ::std::os::raw::c_int,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_recoveryWallet(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ mnemonic: *const ::std::os::raw::c_char,
+ networkType: ::std::os::raw::c_int,
+ restoreHeight: u64,
+ kdfRounds: u64,
+ seedOffset: *const ::std::os::raw::c_char,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_createWalletFromKeys(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ language: *const ::std::os::raw::c_char,
+ nettype: ::std::os::raw::c_int,
+ restoreHeight: u64,
+ addressString: *const ::std::os::raw::c_char,
+ viewKeyString: *const ::std::os::raw::c_char,
+ spendKeyString: *const ::std::os::raw::c_char,
+ kdf_rounds: u64,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_createDeterministicWalletFromSpendKey(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ language: *const ::std::os::raw::c_char,
+ nettype: ::std::os::raw::c_int,
+ restoreHeight: u64,
+ spendKeyString: *const ::std::os::raw::c_char,
+ kdf_rounds: u64,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_createWalletFromDevice(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ nettype: ::std::os::raw::c_int,
+ deviceName: *const ::std::os::raw::c_char,
+ restoreHeight: u64,
+ subaddressLookahead: *const ::std::os::raw::c_char,
+ viewKeyString: *const ::std::os::raw::c_char,
+ spendKeyString: *const ::std::os::raw::c_char,
+ kdf_rounds: u64,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_createWalletFromPolyseed(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ nettype: ::std::os::raw::c_int,
+ mnemonic: *const ::std::os::raw::c_char,
+ passphrase: *const ::std::os::raw::c_char,
+ newWallet: bool,
+ restore_height: u64,
+ kdf_rounds: u64,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_closeWallet(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ store: bool,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_walletExists(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_verifyWalletPassword(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ keys_file_name: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ no_spend_key: bool,
+ kdf_rounds: u64,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_queryWalletDevice(
+ device_type: ::std::os::raw::c_int,
+ keys_file_name: *const ::std::os::raw::c_char,
+ password: *const ::std::os::raw::c_char,
+ kdf_rounds: u64,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_findWallets(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ path: *const ::std::os::raw::c_char,
+ separator: *const ::std::os::raw::c_char,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_errorString(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_setDaemonAddress(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ address: *const ::std::os::raw::c_char,
+ );
+}
+extern "C" {
+ pub fn MONERO_WalletManager_blockchainHeight(wm_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_blockchainTargetHeight(wm_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_networkDifficulty(wm_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_miningHashRate(wm_ptr: *mut ::std::os::raw::c_void) -> f64;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_blockTarget(wm_ptr: *mut ::std::os::raw::c_void) -> u64;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_isMining(wm_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_startMining(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ address: *const ::std::os::raw::c_char,
+ threads: u32,
+ backgroundMining: bool,
+ ignoreBattery: bool,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_stopMining(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ address: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_resolveOpenAlias(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ address: *const ::std::os::raw::c_char,
+ dnssec_valid: bool,
+ ) -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_WalletManager_setProxy(
+ wm_ptr: *mut ::std::os::raw::c_void,
+ address: *const ::std::os::raw::c_char,
+ ) -> bool;
+}
+pub const LogLevel_Silent: ::std::os::raw::c_int = -1;
+pub const LogLevel_0: ::std::os::raw::c_int = 0;
+pub const LogLevel_1: ::std::os::raw::c_int = 1;
+pub const LogLevel_2: ::std::os::raw::c_int = 2;
+pub const LogLevel_3: ::std::os::raw::c_int = 3;
+pub const LogLevel_4: ::std::os::raw::c_int = 4;
+pub const LogLevel_Min: ::std::os::raw::c_int = -1;
+pub const LogLevel_Max: ::std::os::raw::c_int = 4;
+extern "C" {
+ pub fn MONERO_WalletManagerFactory_getWalletManager() -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_WalletManagerFactory_setLogLevel(level: ::std::os::raw::c_int);
+}
+extern "C" {
+ pub fn MONERO_WalletManagerFactory_setLogCategories(categories: *const ::std::os::raw::c_char);
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test0();
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test1(x: bool) -> bool;
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test2(x: ::std::os::raw::c_int) -> ::std::os::raw::c_int;
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test3(x: u64) -> u64;
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test4(x: u64) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test5() -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_DEBUG_test5_std() -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_DEBUG_isPointerNull(wallet_ptr: *mut ::std::os::raw::c_void) -> bool;
+}
+extern "C" {
+ pub fn MONERO_cw_getWalletListener(
+ wallet_ptr: *mut ::std::os::raw::c_void,
+ ) -> *mut ::std::os::raw::c_void;
+}
+extern "C" {
+ pub fn MONERO_cw_WalletListener_resetNeedToRefresh(
+ cw_walletListener_ptr: *mut ::std::os::raw::c_void,
+ );
+}
+extern "C" {
+ pub fn MONERO_cw_WalletListener_isNeedToRefresh(
+ cw_walletListener_ptr: *mut ::std::os::raw::c_void,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_cw_WalletListener_isNewTransactionExist(
+ cw_walletListener_ptr: *mut ::std::os::raw::c_void,
+ ) -> bool;
+}
+extern "C" {
+ pub fn MONERO_cw_WalletListener_resetIsNewTransactionExist(
+ cw_walletListener_ptr: *mut ::std::os::raw::c_void,
+ );
+}
+extern "C" {
+ pub fn MONERO_cw_WalletListener_height(
+ cw_walletListener_ptr: *mut ::std::os::raw::c_void,
+ ) -> u64;
+}
+extern "C" {
+ pub fn MONERO_free(ptr: *mut ::std::os::raw::c_void);
+}
+extern "C" {
+ pub fn MONERO_checksum_wallet2_api_c_h() -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_checksum_wallet2_api_c_cpp() -> *const ::std::os::raw::c_char;
+}
+extern "C" {
+ pub fn MONERO_checksum_wallet2_api_c_exp() -> *const ::std::os::raw::c_char;
+}
diff --git a/impls/monero.rs/src/lib.rs b/impls/monero.rs/src/lib.rs
new file mode 100644
index 0000000..77ea240
--- /dev/null
+++ b/impls/monero.rs/src/lib.rs
@@ -0,0 +1,450 @@
+use std::ffi::{CStr, CString};
+use std::os::raw::{c_int, c_void};
+use std::ptr::NonNull;
+use std::sync::Arc;
+
+mod bindings;
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum NetworkType {
+ Mainnet = bindings::NetworkType_MAINNET as isize,
+ Testnet = bindings::NetworkType_TESTNET as isize,
+ Stagenet = bindings::NetworkType_STAGENET as isize,
+}
+
+impl NetworkType {
+ pub fn from_c_int(value: c_int) -> Option<Self> {
+ match value {
+ bindings::NetworkType_MAINNET => Some(NetworkType::Mainnet),
+ bindings::NetworkType_TESTNET => Some(NetworkType::Testnet),
+ bindings::NetworkType_STAGENET => Some(NetworkType::Stagenet),
+ _ => None,
+ }
+ }
+
+ pub fn to_c_int(self) -> c_int {
+ self as c_int
+ }
+}
+
+#[derive(Debug)]
+pub enum WalletError {
+ NullPointer,
+ FfiError(String),
+ WalletErrorCode(c_int, String),
+}
+
+pub type WalletResult<T> = Result<T, WalletError>;
+
+pub struct WalletManager {
+ ptr: NonNull<c_void>,
+}
+
+impl WalletManager {
+ /// Creates a new `WalletManager` using the statically linked `MONERO_WalletManagerFactory_getWalletManager`.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use monero_c_rust::WalletManager;
+ /// let manager = WalletManager::new();
+ /// assert!(manager.is_ok());
+ /// ```
+ pub fn new() -> WalletResult<Arc<Self>> {
+ unsafe {
+ let ptr = bindings::MONERO_WalletManagerFactory_getWalletManager();
+ let ptr = NonNull::new(ptr).ok_or(WalletError::NullPointer)?;
+ Ok(Arc::new(WalletManager { ptr }))
+ }
+ }
+
+ /// Creates a new wallet.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use monero_c_rust::{WalletManager, NetworkType};
+ /// use std::fs;
+ /// use std::path::Path;
+ ///
+ /// let manager = WalletManager::new().unwrap();
+ /// let wallet = manager.create_wallet("wallet_name", "password", "English", NetworkType::Mainnet);
+ /// assert!(wallet.is_ok());
+ ///
+ /// // Cleanup: remove the wallet file and its corresponding keys file, if they exist.
+ /// if Path::new("wallet_name").exists() {
+ /// fs::remove_file("wallet_name").expect("Failed to delete test wallet");
+ /// }
+ /// if Path::new("wallet_name.keys").exists() {
+ /// fs::remove_file("wallet_name.keys").expect("Failed to delete test wallet keys");
+ /// }
+ /// ```
+ pub fn create_wallet(
+ self: &Arc<Self>,
+ path: &str,
+ password: &str,
+ language: &str,
+ network_type: NetworkType,
+ ) -> WalletResult<Wallet> {
+ let c_path = CString::new(path).map_err(|_| WalletError::FfiError("Invalid path".to_string()))?;
+ let c_password = CString::new(password).map_err(|_| WalletError::FfiError("Invalid password".to_string()))?;
+ let c_language = CString::new(language).map_err(|_| WalletError::FfiError("Invalid language".to_string()))?;
+
+ unsafe {
+ let wallet_ptr = bindings::MONERO_WalletManager_createWallet(
+ self.ptr.as_ptr(),
+ c_path.as_ptr(),
+ c_password.as_ptr(),
+ c_language.as_ptr(),
+ network_type.to_c_int(),
+ );
+
+ NonNull::new(wallet_ptr)
+ .map(|ptr| Wallet { ptr, manager: Arc::clone(self) })
+ .ok_or(WalletError::NullPointer)
+ }
+ }
+}
+
+pub struct Wallet {
+ ptr: NonNull<c_void>,
+ manager: Arc<WalletManager>,
+}
+
+impl Wallet {
+ /// Retrieves the wallet's seed with an optional offset.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use monero_c_rust::{WalletManager, NetworkType};
+ /// use tempfile::TempDir;
+ /// use std::fs;
+ ///
+ /// let temp_dir = TempDir::new().expect("Failed to create temporary directory");
+ /// let wallet_path = temp_dir.path().join("wallet_name");
+ /// let wallet_str = wallet_path.to_str().unwrap();
+ ///
+ /// let manager = WalletManager::new().unwrap();
+ /// let wallet_result = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet);
+ /// assert!(wallet_result.is_ok(), "Failed to create wallet: {:?}", wallet_result.err());
+ /// let wallet = wallet_result.unwrap();
+ /// let seed = wallet.get_seed("");
+ /// assert!(seed.is_ok(), "Failed to get seed: {:?}", seed.err());
+ /// let seed = seed.unwrap();
+ /// assert!(!seed.is_empty(), "Seed should not be empty");
+ ///
+ /// // Clean up wallet files.
+ /// fs::remove_file(wallet_str).expect("Failed to delete test wallet");
+ /// fs::remove_file(format!("{}.keys", wallet_str)).expect("Failed to delete test wallet keys");
+ /// ```
+ pub fn get_seed(&self, seed_offset: &str) -> WalletResult<String> {
+ let c_seed_offset = CString::new(seed_offset)
+ .map_err(|_| WalletError::FfiError("Invalid seed_offset".to_string()))?;
+
+ unsafe {
+ let seed_ptr = bindings::MONERO_Wallet_seed(self.ptr.as_ptr(), c_seed_offset.as_ptr());
+ if seed_ptr.is_null() {
+ Err(self.get_last_error())
+ } else {
+ let seed = CStr::from_ptr(seed_ptr)
+ .to_string_lossy()
+ .into_owned();
+ if seed.is_empty() {
+ Err(WalletError::FfiError("Received empty seed".to_string()))
+ } else {
+ Ok(seed)
+ }
+ }
+ }
+ }
+
+ /// Retrieves the wallet's address for the given account and address index.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use monero_c_rust::{WalletManager, NetworkType};
+ /// use tempfile::TempDir;
+ /// use std::fs;
+ ///
+ /// let temp_dir = TempDir::new().expect("Failed to create temporary directory");
+ /// let wallet_path = temp_dir.path().join("wallet_name");
+ /// let wallet_str = wallet_path.to_str().unwrap();
+ ///
+ /// let manager = WalletManager::new().unwrap();
+ /// let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet).unwrap();
+ /// let address = wallet.get_address(0, 0);
+ /// assert!(address.is_ok(), "Failed to get address: {:?}", address.err());
+ ///
+ /// // Clean up wallet files.
+ /// fs::remove_file(wallet_str).expect("Failed to delete test wallet");
+ /// fs::remove_file(format!("{}.keys", wallet_str)).expect("Failed to delete test wallet keys");
+ /// ```
+ pub fn get_address(&self, account_index: u64, address_index: u64) -> WalletResult<String> {
+ unsafe {
+ let address_ptr = bindings::MONERO_Wallet_address(self.ptr.as_ptr(), account_index, address_index);
+ if address_ptr.is_null() {
+ Err(self.get_last_error())
+ } else {
+ let address = CStr::from_ptr(address_ptr)
+ .to_string_lossy()
+ .into_owned();
+ Ok(address)
+ }
+ }
+ }
+
+ /// Checks if the wallet is deterministic.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use monero_c_rust::{WalletManager, NetworkType};
+ /// use tempfile::TempDir;
+ /// use std::fs;
+ ///
+ /// let temp_dir = TempDir::new().expect("Failed to create temporary directory");
+ /// let wallet_path = temp_dir.path().join("wallet_name");
+ /// let wallet_str = wallet_path.to_str().unwrap();
+ ///
+ /// let manager = WalletManager::new().unwrap();
+ /// let wallet_result = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet);
+ /// assert!(wallet_result.is_ok(), "Failed to create wallet: {:?}", wallet_result.err());
+ /// let wallet = wallet_result.unwrap();
+ /// let is_deterministic = wallet.is_deterministic();
+ /// assert!(is_deterministic.is_ok(), "Failed to check if wallet is deterministic: {:?}", is_deterministic.err());
+ /// assert!(is_deterministic.unwrap(), "Wallet should be deterministic");
+ ///
+ /// // Clean up wallet files.
+ /// fs::remove_file(wallet_str).expect("Failed to delete test wallet");
+ /// fs::remove_file(format!("{}.keys", wallet_str)).expect("Failed to delete test wallet keys");
+ /// ```
+ pub fn is_deterministic(&self) -> WalletResult<bool> {
+ unsafe {
+ let result = bindings::MONERO_Wallet_isDeterministic(self.ptr.as_ptr());
+ Ok(result)
+ }
+ }
+
+ /// Retrieves the last error from the wallet.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use monero_c_rust::{WalletManager, NetworkType, WalletError};
+ /// let manager = WalletManager::new().unwrap();
+ /// // Intentionally pass an invalid wallet to force an error.
+ /// let invalid_wallet = manager.create_wallet("", "", "", NetworkType::Mainnet);
+ /// if let Err(err) = invalid_wallet {
+ /// if let WalletError::WalletErrorCode(_, error_msg) = err {
+ /// // Check that an error message was produced
+ /// assert!(!error_msg.is_empty(), "Error message should not be empty");
+ /// }
+ /// }
+ /// ```
+ pub fn get_last_error(&self) -> WalletError {
+ unsafe {
+ let error_ptr = bindings::MONERO_Wallet_errorString(self.ptr.as_ptr());
+ let status = bindings::MONERO_Wallet_status(self.ptr.as_ptr());
+
+ let error_msg = if error_ptr.is_null() {
+ "Unknown error".to_string()
+ } else {
+ CStr::from_ptr(error_ptr)
+ .to_string_lossy()
+ .into_owned()
+ };
+
+ WalletError::WalletErrorCode(status, error_msg)
+ }
+ }
+}
+
+impl Drop for Wallet {
+ fn drop(&mut self) {
+ unsafe {
+ bindings::MONERO_WalletManager_closeWallet(
+ self.manager.ptr.as_ptr(),
+ self.ptr.as_ptr(),
+ false, // Don't save the wallet by default.
+ );
+ }
+ }
+}
+
+#[cfg(test)]
+use tempfile::TempDir;
+#[cfg(test)]
+use std::fs;
+
+#[cfg(test)]
+fn check_and_delete_existing_wallets(temp_dir: &TempDir) -> std::io::Result<()> {
+ let test_wallet_names = &["wallet_name", "mainnet_wallet", "testnet_wallet", "stagenet_wallet"];
+
+ for name in test_wallet_names {
+ let wallet_file = temp_dir.path().join(name);
+ let keys_file = temp_dir.path().join(format!("{}.keys", name));
+
+ if wallet_file.exists() {
+ fs::remove_file(&wallet_file)?;
+ }
+ if keys_file.exists() {
+ fs::remove_file(&keys_file)?;
+ }
+ }
+ Ok(())
+}
+
+#[cfg(test)]
+fn setup() -> WalletResult<(Arc<WalletManager>, TempDir)> {
+ let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
+ check_and_delete_existing_wallets(&temp_dir).expect("Failed to clean up existing wallets");
+
+ let manager = WalletManager::new()?;
+ Ok((manager, temp_dir))
+}
+
+#[cfg(test)]
+fn teardown(temp_dir: &TempDir) -> std::io::Result<()> {
+ check_and_delete_existing_wallets(temp_dir)
+}
+
+#[test]
+fn test_wallet_manager_creation() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet_result = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet);
+ assert!(wallet_result.is_ok(), "WalletManager creation failed");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_wallet_creation() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet);
+ assert!(wallet.is_ok(), "Failed to create wallet");
+ let wallet = wallet.unwrap();
+ assert!(wallet.is_deterministic().is_ok(), "Wallet creation seems to have failed");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_get_seed() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet).expect("Failed to create wallet");
+ let result = wallet.get_seed("");
+ assert!(result.is_ok(), "Failed to get seed: {:?}", result.err());
+ assert!(!result.unwrap().is_empty(), "Seed is empty");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_get_address() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet).expect("Failed to create wallet");
+ let result = wallet.get_address(0, 0);
+ assert!(result.is_ok(), "Failed to get address: {:?}", result.err());
+ assert!(!result.unwrap().is_empty(), "Address is empty");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_is_deterministic() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet).expect("Failed to create wallet");
+ let result = wallet.is_deterministic();
+ assert!(result.is_ok(), "Failed to check if wallet is deterministic: {:?}", result.err());
+ assert!(result.unwrap(), "Wallet should be deterministic");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_wallet_creation_with_different_networks() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallets = vec![
+ ("mainnet_wallet", NetworkType::Mainnet),
+ ("testnet_wallet", NetworkType::Testnet),
+ ("stagenet_wallet", NetworkType::Stagenet),
+ ];
+
+ for (name, net_type) in wallets {
+ let wallet_path = temp_dir.path().join(name);
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", net_type);
+ assert!(wallet.is_ok(), "Failed to create wallet: {}", name);
+ }
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_multiple_address_generation() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet).expect("Failed to create wallet");
+
+ for i in 0..5 {
+ let result = wallet.get_address(0, i);
+ assert!(result.is_ok(), "Failed to get address {}: {:?}", i, result.err());
+ assert!(!result.unwrap().is_empty(), "Address {} is empty", i);
+ }
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_wallet_error_display() {
+ // Test WalletError::FfiError variant.
+ let error = WalletError::FfiError("Test error".to_string());
+ match error {
+ WalletError::FfiError(msg) => assert_eq!(msg, "Test error"),
+ _ => panic!("Expected FfiError variant"),
+ }
+
+ // Test WalletError::NullPointer variant.
+ let error = WalletError::NullPointer;
+ match error {
+ WalletError::NullPointer => assert!(true),
+ _ => panic!("Expected NullPointer variant"),
+ }
+
+ // Test WalletError::WalletErrorCode variant.
+ let error = WalletError::WalletErrorCode(2, "Sample wallet error".to_string());
+ match error {
+ WalletError::WalletErrorCode(code, msg) => {
+ assert_eq!(code, 2);
+ assert_eq!(msg, "Sample wallet error");
+ },
+ _ => panic!("Expected WalletErrorCode variant"),
+ }
+}
diff --git a/impls/monero.rs/tests/integration_tests.rs b/impls/monero.rs/tests/integration_tests.rs
new file mode 100644
index 0000000..0e84977
--- /dev/null
+++ b/impls/monero.rs/tests/integration_tests.rs
@@ -0,0 +1,256 @@
+use monero_c_rust::{WalletManager, NetworkType, WalletError, WalletResult};
+use std::fs;
+use std::sync::Arc;
+use std::time::Instant;
+use tempfile::TempDir;
+
+const TEST_WALLET_NAMES: &[&str] = &[
+ "test_wallet",
+ "mainnet_wallet",
+ "testnet_wallet",
+ "stagenet_wallet",
+];
+
+/// Helper function to clean up existing wallet files in a temporary directory.
+fn check_and_delete_existing_wallets(temp_dir: &TempDir) -> std::io::Result<()> {
+ for name in TEST_WALLET_NAMES {
+ // Construct absolute paths for wallet files.
+ let wallet_file = temp_dir.path().join(name);
+ let keys_file = temp_dir.path().join(format!("{}.keys", name));
+ let address_file = temp_dir.path().join(format!("{}.address.txt", name)); // Added
+
+ // Delete wallet file if it exists.
+ if wallet_file.exists() {
+ if let Err(e) = fs::remove_file(&wallet_file) {
+ println!("Warning: Failed to delete wallet file {:?}: {}", wallet_file, e);
+ } else {
+ println!("Deleted existing wallet file: {:?}", wallet_file);
+ }
+ }
+
+ // Delete keys file if it exists.
+ if keys_file.exists() {
+ if let Err(e) = fs::remove_file(&keys_file) {
+ println!("Warning: Failed to delete keys file {:?}: {}", keys_file, e);
+ } else {
+ println!("Deleted existing keys file: {:?}", keys_file);
+ }
+ }
+
+ // Delete address file if it exists.
+ if address_file.exists() {
+ if let Err(e) = fs::remove_file(&address_file) {
+ println!("Warning: Failed to delete address file {:?}: {}", address_file, e);
+ } else {
+ println!("Deleted existing address file: {:?}", address_file);
+ }
+ }
+ }
+ Ok(())
+}
+
+/// Sets up the test environment by creating a temporary directory and initializing the WalletManager.
+///
+/// Returns:
+/// - An `Arc` wrapped `WalletManager` instance.
+/// - A `TempDir` representing the temporary directory.
+fn setup() -> WalletResult<(Arc<WalletManager>, TempDir)> {
+ println!("Setting up test environment...");
+ let temp_dir = tempfile::tempdir().expect("Failed to create temporary directory");
+ check_and_delete_existing_wallets(&temp_dir).expect("Failed to clean up existing wallets");
+
+ println!("Creating WalletManager...");
+ let start = Instant::now();
+ let manager = WalletManager::new()?;
+ println!("WalletManager creation took {:?}", start.elapsed());
+
+ Ok((manager, temp_dir))
+}
+
+/// Tears down the test environment by deleting wallet files.
+///
+/// Args:
+/// - `temp_dir`: Reference to the temporary directory.
+///
+/// Returns:
+/// - `Result<(), std::io::Error>` indicating success or failure.
+fn teardown(temp_dir: &TempDir) -> std::io::Result<()> {
+ println!("Tearing down test environment...");
+ check_and_delete_existing_wallets(temp_dir)
+}
+
+#[test]
+fn test_wallet_manager_creation() {
+ println!("Running test_wallet_manager_creation");
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ // Construct the full path for the wallet within temp_dir.
+ let wallet_path = temp_dir.path().join("test_wallet");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet_result = manager.create_wallet(wallet_str, "password123", "English", NetworkType::Mainnet);
+ assert!(wallet_result.is_ok(), "WalletManager creation seems to have failed");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_wallet_creation() {
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ let wallet_path = temp_dir.path().join("wallet_name");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", NetworkType::Mainnet);
+ assert!(wallet.is_ok(), "Failed to create wallet");
+ let wallet = wallet.unwrap();
+ assert!(wallet.is_deterministic().is_ok(), "Wallet creation seems to have failed");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_get_seed() {
+ println!("Running test_get_seed");
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ // Construct the full path for the wallet within temp_dir.
+ let wallet_path = temp_dir.path().join("test_wallet");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager
+ .create_wallet(wallet_str, "password123", "English", NetworkType::Mainnet)
+ .expect("Failed to create wallet");
+ println!("Attempting to get seed...");
+ let start = Instant::now();
+ let result = wallet.get_seed("");
+ println!("get_seed took {:?}", start.elapsed());
+ assert!(result.is_ok(), "Failed to get seed: {:?}", result.err());
+ assert!(!result.unwrap().is_empty(), "Seed is empty");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_get_address() {
+ println!("Running test_get_address");
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ // Construct the full path for the wallet within temp_dir.
+ let wallet_path = temp_dir.path().join("test_wallet");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager
+ .create_wallet(wallet_str, "password123", "English", NetworkType::Mainnet)
+ .expect("Failed to create wallet");
+ println!("Attempting to get address...");
+ let start = Instant::now();
+ let result = wallet.get_address(0, 0);
+ println!("get_address took {:?}", start.elapsed());
+ assert!(result.is_ok(), "Failed to get address: {:?}", result.err());
+ assert!(!result.unwrap().is_empty(), "Address is empty");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_is_deterministic() {
+ println!("Running test_is_deterministic");
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ // Construct the full path for the wallet within temp_dir.
+ let wallet_path = temp_dir.path().join("test_wallet");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager
+ .create_wallet(wallet_str, "password123", "English", NetworkType::Mainnet)
+ .expect("Failed to create wallet");
+ println!("Checking if wallet is deterministic...");
+ let start = Instant::now();
+ let result = wallet.is_deterministic();
+ println!("is_deterministic check took {:?}", start.elapsed());
+ assert!(result.is_ok(), "Failed to check if wallet is deterministic: {:?}", result.err());
+ assert!(result.unwrap(), "Wallet should be deterministic");
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_wallet_creation_with_different_networks() {
+ println!("Running test_wallet_creation_with_different_networks");
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ // Define wallet names and corresponding network types.
+ let wallets = vec![
+ ("mainnet_wallet", NetworkType::Mainnet),
+ ("testnet_wallet", NetworkType::Testnet),
+ ("stagenet_wallet", NetworkType::Stagenet),
+ ];
+
+ for (name, net_type) in wallets {
+ println!("Creating wallet: {} on network type {:?}", name, net_type);
+
+ // Construct the full path for each wallet within temp_dir.
+ let wallet_path = temp_dir.path().join(name);
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager.create_wallet(wallet_str, "password", "English", net_type);
+ assert!(wallet.is_ok(), "Failed to create wallet: {}", name);
+ }
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_multiple_address_generation() {
+ println!("Running test_multiple_address_generation");
+ let (manager, temp_dir) = setup().expect("Failed to set up test environment");
+
+ // Construct the full path for the wallet within temp_dir.
+ let wallet_path = temp_dir.path().join("test_wallet");
+ let wallet_str = wallet_path.to_str().expect("Failed to convert wallet path to string");
+
+ let wallet = manager
+ .create_wallet(wallet_str, "password123", "English", NetworkType::Mainnet)
+ .expect("Failed to create wallet");
+
+ for i in 0..5 {
+ println!("Generating address {}...", i);
+ let start = Instant::now();
+ let result = wallet.get_address(0, i);
+ println!("Address generation took {:?}", start.elapsed());
+ assert!(result.is_ok(), "Failed to get address {}: {:?}", i, result.err());
+ assert!(!result.unwrap().is_empty(), "Address {} is empty", i);
+ }
+
+ teardown(&temp_dir).expect("Failed to clean up after test");
+}
+
+#[test]
+fn test_wallet_error_display() {
+ println!("Running test_wallet_error_display");
+
+ // Test WalletError::FfiError variant.
+ let error = WalletError::FfiError("Test error".to_string());
+ match error {
+ WalletError::FfiError(msg) => assert_eq!(msg, "Test error"),
+ _ => panic!("Expected FfiError variant"),
+ }
+
+ // Test WalletError::NullPointer variant.
+ let error = WalletError::NullPointer;
+ match error {
+ WalletError::NullPointer => assert!(true),
+ _ => panic!("Expected NullPointer variant"),
+ }
+
+ // Test WalletError::WalletErrorCode variant.
+ let error = WalletError::WalletErrorCode(2, "Sample wallet error".to_string());
+ match error {
+ WalletError::WalletErrorCode(code, msg) => {
+ assert_eq!(code, 2);
+ assert_eq!(msg, "Sample wallet error");
+ },
+ _ => panic!("Expected WalletErrorCode variant"),
+ }
+}