From 0a418e15df9fa9d0f63803d838346ccff0adcf23 Mon Sep 17 00:00:00 2001
From: CalDescent <>
Date: Sun, 7 Aug 2022 17:23:38 +0100
Subject: [PATCH] Initial commit, originally based on code from
https://github.com/PirateNetwork/cordova-plugin-litewallet
---
.gitignore | 4 +
LICENSE | 21 ++++
README.md | 22 ++++
src/.cargo/config | 13 ++
src/Cargo.toml | 8 ++
src/Dockerfile | 5 +
src/build-docker.sh | 3 +
src/crosscompile.sh | 15 +++
src/lib/Cargo.toml | 25 ++++
src/lib/src/lib.rs | 297 ++++++++++++++++++++++++++++++++++++++++++++
src/main/Cargo.toml | 16 +++
src/main/build.sh | 97 +++++++++++++++
src/main/src/lib.rs | 214 +++++++++++++++++++++++++++++++
src/rust-toolchain | 1 +
14 files changed, 741 insertions(+)
create mode 100644 .gitignore
create mode 100644 LICENSE
create mode 100644 README.md
create mode 100644 src/.cargo/config
create mode 100644 src/Cargo.toml
create mode 100644 src/Dockerfile
create mode 100755 src/build-docker.sh
create mode 100755 src/crosscompile.sh
create mode 100644 src/lib/Cargo.toml
create mode 100644 src/lib/src/lib.rs
create mode 100644 src/main/Cargo.toml
create mode 100755 src/main/build.sh
create mode 100644 src/main/src/lib.rs
create mode 100644 src/rust-toolchain
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