commit 0a418e15df9fa9d0f63803d838346ccff0adcf23 Author: CalDescent <> Date: Sun Aug 7 17:23:38 2022 +0100 Initial commit, originally based on code from https://github.com/PirateNetwork/cordova-plugin-litewallet diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3f3548 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +/src/target +openssl* +.DS_Store +Cargo.lock diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a42d43c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 Zero Currency Coin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..b5d6b48 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Pirate Chain LiteWalletJNI Build System +Based on code from https://github.com/PirateNetwork/cordova-plugin-litewallet
+Adapted in July 2022 by Qortal dev team

+ + +### Native Builds ### + +``` +cd src/ +cargo build --release +ls -l target/release +``` + + +### Cross Compilation via Docker ### + +``` +cd src/ +./build-docker.sh +./crosscompile.sh +ls -l target +``` diff --git a/src/.cargo/config b/src/.cargo/config new file mode 100644 index 0000000..68518b2 --- /dev/null +++ b/src/.cargo/config @@ -0,0 +1,13 @@ +[target.arm-unknown-linux-gnueabihf] +ar = "/opt/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-ar" +linker = "/opt/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc" + +[target.aarch64-unknown-linux-gnu] +ar = "/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-ar" +linker = "/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc" + +[target.x86_64-apple-darwin] +rustflags = [ + "-C", "link-arg=-undefined", + "-C", "link-arg=dynamic_lookup", +] diff --git a/src/Cargo.toml b/src/Cargo.toml new file mode 100644 index 0000000..b29d076 --- /dev/null +++ b/src/Cargo.toml @@ -0,0 +1,8 @@ +[workspace] +members = [ + "lib", + "main" +] + +[profile.release] +debug = false diff --git a/src/Dockerfile b/src/Dockerfile new file mode 100644 index 0000000..25de1f5 --- /dev/null +++ b/src/Dockerfile @@ -0,0 +1,5 @@ +FROM rust:1.60.0-slim-buster +RUN apt-get update && apt-get install -y tar unzip wget curl jq build-essential mingw-w64 +RUN cd /opt && curl https://codeload.github.com/raspberrypi/tools/tar.gz/master | tar -xz --strip=2 tools-master/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf +RUN wget "https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz?revision=61c3be5d-5175-4db6-9030-b565aae9f766&la=en&hash=0A37024B42028A9616F56A51C2D20755C5EBBCD7" -O gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz && mkdir -p /opt/arm/9 && tar Jxf gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz -C /opt/arm/9 +WORKDIR /build diff --git a/src/build-docker.sh b/src/build-docker.sh new file mode 100755 index 0000000..4aa8064 --- /dev/null +++ b/src/build-docker.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +docker build -t piratejni . diff --git a/src/crosscompile.sh b/src/crosscompile.sh new file mode 100755 index 0000000..45b6394 --- /dev/null +++ b/src/crosscompile.sh @@ -0,0 +1,15 @@ +INSTANCE_NAME="piratejni" +EXISTING_CONTAINER_ID=$(docker ps -aqf "name=${INSTANCE_NAME}") +EXISTING_RUNNING_CONTAINER_ID=$(docker ps -aqf "name=${INSTANCE_NAME}" --filter status=running) + +if [ -z "${EXISTING_RUNNING_CONTAINER_ID}" ]; then + + # Container not running - start it + echo "Starting new container ${INSTANCE_NAME}..." + docker rm "${INSTANCE_NAME}" + docker run -v "$(pwd)":/build --name "${INSTANCE_NAME}" -it "${INSTANCE_NAME}" "./main/build.sh" + +else + # Already running + echo "${INSTANCE_NAME} is already running with container ID ${EXISTING_CONTAINER_ID}. Doing nothing." +fi diff --git a/src/lib/Cargo.toml b/src/lib/Cargo.toml new file mode 100644 index 0000000..7733c1e --- /dev/null +++ b/src/lib/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "rustlib" +version = "1.0.0" +authors = ["Aditya Kulkarni "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +jni = { version = "0.10.2", default-features = false } +zecwalletlitelib = { git="https://github.com/Qortal/piratewallet-light-cli", default-features=false, rev="9d6704ec42cb5429d8433c486211891b2216ea4c" } +lazy_static = "1.4.0" +num-integer = "0.1.44" +android_logger = "0.8.6" +log = "0.4.8" +base64 = "0.11.0" + +serde = "1.0" +serde_json = "1.0" +serde_derive = "1.0" +hex = "0.3" +hex-serde = "0.1" + +tiny-bip39 = "0.6.2" +rand = "0.7.2" diff --git a/src/lib/src/lib.rs b/src/lib/src/lib.rs new file mode 100644 index 0000000..cd9821e --- /dev/null +++ b/src/lib/src/lib.rs @@ -0,0 +1,297 @@ +#[macro_use] +extern crate lazy_static; + +use std::sync::{Mutex, Arc}; +use std::cell::RefCell; + +use base64::{encode, decode}; +use bip39::{Mnemonic, Language}; +use rand::{Rng, rngs::OsRng}; + +extern crate serde; +#[macro_use] extern crate serde_json; +extern crate serde_derive; +use serde_derive::Deserialize; + +use zecwalletlitelib::{commands, lightclient::{LightClient, LightClientConfig}}; + + +#[derive(Deserialize, Clone)] +pub struct JsAddressParameters { + pub coin_type: String, + pub hrp_sapling_extended_spending_key: String, + pub hrp_sapling_extended_full_viewing_key: String, + pub hrp_sapling_payment_address: String, + #[serde(with = "hex_serde")] + pub b58_pubkey_address_prefix: [u8; 2], + #[serde(with = "hex_serde")] + pub b58_script_address_prefix: [u8; 2], +} + + +pub fn set_address_params(mut config: LightClientConfig, params: &str) -> LightClientConfig { + + let js_params: JsAddressParameters = match serde_json::from_str(¶ms) { + Ok(js) => js, + Err(_) => {return config} + }; + + let ct: u32 = match js_params.coin_type.parse() { + Ok(s) => s, + Err(_) => return config + }; + + if js_params.hrp_sapling_extended_spending_key.len() == 0 {return config} + if js_params.hrp_sapling_extended_full_viewing_key.len() == 0 {return config} + if js_params.hrp_sapling_payment_address.len() == 0 {return config} + if js_params.b58_pubkey_address_prefix.len() != 2 {return config} + if js_params.b58_script_address_prefix.len() != 2 {return config} + + LightClientConfig::set_coin_type(&mut config, ct); + LightClientConfig::set_hrp_sapling_extended_spending_key(&mut config, js_params.hrp_sapling_extended_spending_key); + LightClientConfig::set_hrp_sapling_extended_full_viewing_key(&mut config, js_params.hrp_sapling_extended_full_viewing_key); + LightClientConfig::set_hrp_sapling_payment_address(&mut config, js_params.hrp_sapling_payment_address); + LightClientConfig::set_b58_pubkey_address_prefix(&mut config, js_params.b58_pubkey_address_prefix); + LightClientConfig::set_b58_script_address_prefix(&mut config, js_params.b58_script_address_prefix); + + config +} + + +// We'll use a MUTEX to store a global lightclient instance, +// so we don't have to keep creating it. We need to store it here, in rust +// because we can't return such a complex structure back to JS +lazy_static! { + static ref LIGHTCLIENT: Mutex>>> = Mutex::new(RefCell::new(None)); +} +pub fn init_new(server_uri: String, params: String, sapling_output_b64: String, sapling_spend_b64: String) -> String { + let server = LightClientConfig::get_server_or_default(Some(server_uri)); + let (mut config, latest_block_height) = match LightClientConfig::create(server) { + Ok((c, h)) => (c, h), + Err(e) => { + return format!("Error: {}", e); + } + }; + + //Set Encoding Specifications + config = set_address_params(config, params.as_str()); + + let lightclient = match LightClient::new(&config, latest_block_height) { + Ok(mut l) => { + match l.set_sapling_params(&decode(&sapling_output_b64).unwrap(), &decode(&sapling_spend_b64).unwrap()) { + Ok(_) => l, + Err(e) => return format!("Error: {}", e) + } + }, + Err(e) => { + return format!("Error: {}", e); + } + }; + + let seed = match lightclient.do_seed_phrase() { + Ok(s) => s.dump(), + Err(e) => { + return format!("Error: {}", e); + } + }; + + LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient))); + + seed +} + +pub fn init_from_seed(server_uri: String, params: String, seed: String, birthday: u64, sapling_output_b64: String, sapling_spend_b64: String) -> String { + let server = LightClientConfig::get_server_or_default(Some(server_uri)); + let (mut config, _latest_block_height) = match LightClientConfig::create(server) { + Ok((c, h)) => (c, h), + Err(e) => { + return format!("Error: {}", e); + } + }; + + //Set Encoding Specifications + config = set_address_params(config, params.as_str()); + + let lightclient = match LightClient::new_from_phrase(seed, &config, birthday, false) { + Ok(mut l) => { + match l.set_sapling_params(&decode(&sapling_output_b64).unwrap(), &decode(&sapling_spend_b64).unwrap()) { + Ok(_) => l, + Err(e) => return format!("Error: {}", e) + } + }, + Err(e) => { + return format!("Error: {}", e); + } + }; + + let seed = match lightclient.do_seed_phrase() { + Ok(s) => s.dump(), + Err(e) => { + return format!("Error: {}", e); + } + }; + + LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient))); + + seed +} + +pub fn init_from_b64(server_uri: String, params: String, base64_data: String, sapling_output_b64: String, sapling_spend_b64: String) -> String { + let server = LightClientConfig::get_server_or_default(Some(server_uri)); + let (mut config, _latest_block_height) = match LightClientConfig::create(server) { + Ok((c, h)) => (c, h), + Err(e) => { + let data = json!({ + "initalized": false, + "error": format!("{}", e) + }); + return serde_json::to_string(&data).unwrap(); + } + }; + + //Set Encoding Specifications + config = set_address_params(config, params.as_str()); + + let decoded_bytes = match decode(&base64_data) { + Ok(b) => b, + Err(e) => { + let data = json!({ + "initalized": false, + "error": format!("Decoding Base64 {}", e) + }); + return serde_json::to_string(&data).unwrap(); + } + }; + + let lightclient = match LightClient::read_from_buffer(&config, &decoded_bytes[..]) { + Ok(mut l) => { + match l.set_sapling_params(&decode(&sapling_output_b64).unwrap(), &decode(&sapling_spend_b64).unwrap()) { + Ok(_) => l, + Err(e) => { + let data = json!({ + "initalized": false, + "error": format!("{}", e) + }); + return serde_json::to_string(&data).unwrap(); + } + } + }, + Err(e) => { + + let data = json!({ + "initalized": false, + "error": format!("{}", e) + }); + return serde_json::to_string(&data).unwrap(); + } + }; + + LIGHTCLIENT.lock().unwrap().replace(Some(Arc::new(lightclient))); + + let data = json!({ + "initalized": true, + "error": "none" + }); + + serde_json::to_string(&data).unwrap() + +} + +pub fn save_to_b64() -> String { + // Return the wallet as a base64 encoded string + let lightclient: Arc; + { + let lc = LIGHTCLIENT.lock().unwrap(); + + if lc.borrow().is_none() { + return format!("Error: Light Client is not initialized"); + } + + lightclient = lc.borrow().as_ref().unwrap().clone(); + }; + + match lightclient.do_save_to_buffer() { + Ok(buf) => encode(&buf), + Err(e) => { + format!("Error: {}", e) + } + } +} + +pub fn execute(cmd: String, args_list: String) -> String { + let resp: String; + { + let lightclient: Arc; + { + let lc = LIGHTCLIENT.lock().unwrap(); + + if lc.borrow().is_none() { + return format!("Error: Light Client is not initialized"); + } + + lightclient = lc.borrow().as_ref().unwrap().clone(); + }; + + let args = if args_list.is_empty() { vec![] } else { vec![args_list.as_ref()] }; + resp = commands::do_user_command(&cmd, &args, lightclient.as_ref()).clone(); + }; + + resp +} + +pub fn check_seed_phrase(seed_phrase: &str) ->String { + match Mnemonic::from_phrase(seed_phrase.to_string(), Language::English) { + Ok(_) => { + let data = json!({"checkSeedPhrase": "Ok"}); + return serde_json::to_string(&data).unwrap() + }, + Err(_) => { + let data = json!({"checkSeedPhrase": "Error"}); + return serde_json::to_string(&data).unwrap() + } + }; +} + +pub fn get_seed_phrase() -> String { + + let mut seed_bytes = [0u8; 32]; + let mut system_rng = OsRng; + system_rng.fill(&mut seed_bytes); + + let data = json!({ + "seedPhrase": Mnemonic::from_entropy(&seed_bytes,Language::English,).unwrap().phrase().to_string() + }); + + serde_json::to_string(&data).unwrap() +} + +pub fn get_seed_phrase_from_entropy(entropy: &str) -> String { + + let seed_bytes = entropy.as_bytes(); + + let data = json!({ + "seedPhrase": Mnemonic::from_entropy(&seed_bytes,Language::English,).unwrap().phrase().to_string() + }); + + serde_json::to_string(&data).unwrap() +} + +pub fn get_seed_phrase_from_entropy_b64(entropyb64: &str) -> String { + + let seed_bytes = match decode(&entropyb64) { + Ok(b) => b, + Err(e) => { + let data = json!({ + "initalized": false, + "error": format!("Decoding Base64 {}", e) + }); + return serde_json::to_string(&data).unwrap(); + } + }; + + let data = json!({ + "seedPhrase": Mnemonic::from_entropy(&seed_bytes,Language::English,).unwrap().phrase().to_string() + }); + + serde_json::to_string(&data).unwrap() +} diff --git a/src/main/Cargo.toml b/src/main/Cargo.toml new file mode 100644 index 0000000..7bd0be8 --- /dev/null +++ b/src/main/Cargo.toml @@ -0,0 +1,16 @@ +[package] +name = "rust" +version = "1.0.0" +authors = ["Aditya Kulkarni "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +jni = { version = "0.10.2", default-features = false } +android_logger = "0.8.6" +log = "0.4.8" +rustlib = { path = "../lib" } + +[lib] +crate-type = ["cdylib"] \ No newline at end of file diff --git a/src/main/build.sh b/src/main/build.sh new file mode 100755 index 0000000..34340c5 --- /dev/null +++ b/src/main/build.sh @@ -0,0 +1,97 @@ +#!/bin/bash + +function build_openssl { + # Build openssl + OPENSSL_VERSION="1.1.1e" + OPENSSL_DIRNAME="openssl-${OPENSSL_VERSION}" + OPENSSL_EXT="tar.gz" + OPENSSL_FILENAME="${OPENSSL_DIRNAME}.${OPENSSL_EXT}" + OPENSSL_URL_PREFIX="https://www.openssl.org/source/old/1.1.1/" + OPENSSL_URL="${OPENSSL_URL_PREFIX}${OPENSSL_FILENAME}" + + # Download + if [ ! -f "${OPENSSL_FILENAME}" ]; then + curl "${OPENSSL_URL}" -O "${OPENSSL_FILENAME}" + fi + # Extract + if [ ! -d "${OPENSSL_DIRNAME}" ]; then + tar xvf "${OPENSSL_FILENAME}" + fi + # Build + if [ ! -d "${OPENSSL_DIRNAME}/${OPENSSL_DIRNAME}/${ARCH}" ]; then + cd "${OPENSSL_DIRNAME}" + + chmod +x config + ./config + + make clean + make distclean + + export PATH=${TOOLCHAIN}:${TOOLCHAIN}/bin:$TOOLCHAIN/${ARCH}/bin:$PATH + + INSTALL_DIR=$(pwd)/${OPENSSL_DIRNAME}/${ARCH} + + ./Configure --prefix=${INSTALL_DIR} --openssldir=${INSTALL_DIR}/ssl ${OPENSSL_ARCH} + make -j$(nproc) + make -j$(nproc) install + cd .. + fi +} + +function build_rustlib { + # Build rustlib + export OPENSSL_STATIC=yes + export OPENSSL_LIB_DIR=$(pwd)/${OPENSSL_DIRNAME}/${OPENSSL_DIRNAME}/${ARCH}/lib + export OPENSSL_INCLUDE_DIR=$(pwd)/${OPENSSL_DIRNAME}/${OPENSSL_DIRNAME}/${ARCH}/include + + rustup target add ${RUST_ARCH} + rustup component add rustfmt --toolchain 1.46.0-x86_64-unknown-linux-gnu + rustup show + + cargo build --target ${RUST_ARCH} --release +} + +function build { + local ARCH=$1 + + echo "Building ${ARCH} architecture..." + + if [ "$ARCH" == "arm-linux-gnueabihf" ] + then + export RUST_ARCH="arm-unknown-linux-gnueabihf" + export OPENSSL_ARCH="linux-generic32" + export TOOLCHAIN="/opt/arm-rpi-4.9.3-linux-gnueabihf" + export AR=${TOOLCHAIN}/bin/arm-linux-gnueabihf-ar + export CC=${TOOLCHAIN}/bin/arm-linux-gnueabihf-gcc + + elif [ "$ARCH" == "aarch64-linux-gnu" ] + then + export RUST_ARCH="aarch64-unknown-linux-gnu" + export OPENSSL_ARCH="linux-aarch64" + export TOOLCHAIN="/opt/arm/9/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu" + export AR=${TOOLCHAIN}/bin/aarch64-none-linux-gnu-ar + export CC=${TOOLCHAIN}/bin/aarch64-none-linux-gnu-gcc + + elif [ "$ARCH" == "x86_64-linux" ] + then + export RUST_ARCH="x86_64-unknown-linux-gnu" + export OPENSSL_ARCH="linux-x86_64" + + elif [ "$ARCH" == "x86_64-w64-mingw32" ] + then + export RUST_ARCH="x86_64-pc-windows-gnu" + export OPENSSL_ARCH="mingw64" + export TOOLCHAIN="/etc/alternatives" + export AR=${TOOLCHAIN}/x86_64-w64-mingw32-gcc-ar + export CC=${TOOLCHAIN}/x86_64-w64-mingw32-gcc + export WINDRES=x86_64-w64-mingw32-windres + fi + + build_openssl + build_rustlib +} + +build "x86_64-linux" +build "aarch64-linux-gnu" +#build "x86_64-w64-mingw32" # Build not working +#build "arm-linux-gnueabihf" # Library doesn't support 32bit diff --git a/src/main/src/lib.rs b/src/main/src/lib.rs new file mode 100644 index 0000000..91cae62 --- /dev/null +++ b/src/main/src/lib.rs @@ -0,0 +1,214 @@ +// #![cfg(target_os="android")] +#![allow(non_snake_case)] + +//#[macro_use] extern crate log; +extern crate android_logger; + +use log::Level; +use android_logger::Config; + +use std::ffi::{CString, CStr}; +use jni::JNIEnv; +use jni::objects::{JObject, JString}; +use jni::sys::{jstring}; + + +#[no_mangle] +pub unsafe extern fn Java_com_rust_litewalletjni_LiteWalletJni_initlogging(env: JNIEnv, _: JObject) -> jstring { + android_logger::init_once( + Config::default().with_min_level(Level::Trace), + ); + + let ok = format!("OK"); + let output = env.new_string(ok.as_str()).unwrap(); + return output.into_inner(); +} + +#[no_mangle] +pub unsafe extern "C" fn Java_com_rust_litewalletjni_LiteWalletJni_getseedphrase(env: JNIEnv) -> jstring { + + let results = rustlib::get_seed_phrase(); + //Create string to be passed back to Java + let output = env.new_string(format!("{}", results)).expect("Couldn't create java string!"); + // Finally, extract the raw pointer to return. + output.into_inner() +} + +#[no_mangle] +pub unsafe extern "C" fn Java_com_rust_litewalletjni_LiteWalletJni_getseedphrasefromentropy(env: JNIEnv, _: JObject, input: JString) -> jstring { + + let input: String = env.get_string(input).expect("Couldn't get java string!").into(); + + let results = rustlib::get_seed_phrase_from_entropy(input.as_str()); + //Create string to be passed back to Java + let output = env.new_string(format!("{}", results)).expect("Couldn't create java string!"); + // Finally, extract the raw pointer to return. + output.into_inner() +} + +#[no_mangle] +pub unsafe extern "C" fn Java_com_rust_litewalletjni_LiteWalletJni_getseedphrasefromentropyb64(env: JNIEnv, _: JObject, input: JString) -> jstring { + + let input: String = env.get_string(input).expect("Couldn't get java string!").into(); + + let results = rustlib::get_seed_phrase_from_entropy_b64(input.as_str()); + //Create string to be passed back to Java + let output = env.new_string(format!("{}", results)).expect("Couldn't create java string!"); + // Finally, extract the raw pointer to return. + output.into_inner() +} + +#[no_mangle] +pub unsafe extern "C" fn Java_com_rust_litewalletjni_LiteWalletJni_checkseedphrase(env: JNIEnv, _: JObject, input: JString) -> jstring { + + let input: String = env.get_string(input).expect("Couldn't get java string!").into(); + //generate key + let results = rustlib::check_seed_phrase(input.as_str()); + //Create string to be passed back to Java + let output = env.new_string(format!("{}", results)).expect("Couldn't create java string!"); + // Finally, extract the raw pointer to return. + output.into_inner() +} + +#[no_mangle] +pub unsafe extern fn Java_com_rust_litewalletjni_LiteWalletJni_initnew(env: JNIEnv, _: JObject, j_serveruri: JString, j_params: JString, + j_sapling_output: JString, j_sapling_spend: JString) -> jstring { + let server_uri = CString::from( + CStr::from_ptr( + env.get_string(j_serveruri).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let params = CString::from( + CStr::from_ptr( + env.get_string(j_params).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let sapling_output = CString::from( + CStr::from_ptr( + env.get_string(j_sapling_output).unwrap().as_ptr() + ) + ).into_string().unwrap(); + let sapling_spend = CString::from( + CStr::from_ptr( + env.get_string(j_sapling_spend).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let seed = rustlib::init_new(server_uri, params, sapling_output, sapling_spend); + + let output = env.new_string(seed.as_str()).unwrap(); + output.into_inner() +} + + +#[no_mangle] +pub unsafe extern fn Java_com_rust_litewalletjni_LiteWalletJni_initfromseed(env: JNIEnv, _: JObject, j_serveruri: JString, j_params: JString, + j_seed: JString, j_birthday: JString, j_sapling_output: JString, j_sapling_spend: JString) -> jstring { + let server_uri = CString::from( + CStr::from_ptr( + env.get_string(j_serveruri).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let params = CString::from( + CStr::from_ptr( + env.get_string(j_params).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let seed = CString::from( + CStr::from_ptr( + env.get_string(j_seed).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let birthday = CString::from( + CStr::from_ptr( + env.get_string(j_birthday).unwrap().as_ptr() + ) + ).into_string().unwrap().parse::().unwrap(); + + let sapling_output = CString::from( + CStr::from_ptr( + env.get_string(j_sapling_output).unwrap().as_ptr() + ) + ).into_string().unwrap(); + let sapling_spend = CString::from( + CStr::from_ptr( + env.get_string(j_sapling_spend).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let seed = rustlib::init_from_seed(server_uri, params, seed, birthday, sapling_output, sapling_spend); + + let output = env.new_string(seed.as_str()).unwrap(); + output.into_inner() +} + + +#[no_mangle] +pub unsafe extern fn Java_com_rust_litewalletjni_LiteWalletJni_initfromb64(env: JNIEnv, _: JObject, j_serveruri: JString, j_params: JString, + j_base64: JString, j_sapling_output: JString, j_sapling_spend: JString) -> jstring { + let base64 = CString::from( + CStr::from_ptr( + env.get_string(j_base64).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let server_uri = CString::from( + CStr::from_ptr( + env.get_string(j_serveruri).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let params = CString::from( + CStr::from_ptr( + env.get_string(j_params).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let sapling_output = CString::from( + CStr::from_ptr( + env.get_string(j_sapling_output).unwrap().as_ptr() + ) + ).into_string().unwrap(); + let sapling_spend = CString::from( + CStr::from_ptr( + env.get_string(j_sapling_spend).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let seed = rustlib::init_from_b64(server_uri, params, base64, sapling_output, sapling_spend); + + let output = env.new_string(seed.as_str()).unwrap(); + output.into_inner() +} + +#[no_mangle] +pub unsafe extern fn Java_com_rust_litewalletjni_LiteWalletJni_save(env: JNIEnv, _: JObject) -> jstring { + let encoded = rustlib::save_to_b64(); + let output = env.new_string(encoded.as_str()).unwrap(); + output.into_inner() +} + +#[no_mangle] +pub unsafe extern fn Java_com_rust_litewalletjni_LiteWalletJni_execute(env: JNIEnv, _: JObject, j_command: JString, j_argslist: JString) -> jstring { + let cmd = CString::from( + CStr::from_ptr( + env.get_string(j_command).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let args_list = CString::from( + CStr::from_ptr( + env.get_string(j_argslist).unwrap().as_ptr() + ) + ).into_string().unwrap(); + + let resp = rustlib::execute(cmd, args_list); + + let output = env.new_string(resp.as_str()).unwrap(); + output.into_inner() +} diff --git a/src/rust-toolchain b/src/rust-toolchain new file mode 100644 index 0000000..0a3db35 --- /dev/null +++ b/src/rust-toolchain @@ -0,0 +1 @@ +1.46.0