Browse Source

Initial commit, originally based on code from https://github.com/PirateNetwork/cordova-plugin-litewallet

master
CalDescent 2 years ago
commit
0a418e15df
  1. 4
      .gitignore
  2. 21
      LICENSE
  3. 22
      README.md
  4. 13
      src/.cargo/config
  5. 8
      src/Cargo.toml
  6. 5
      src/Dockerfile
  7. 3
      src/build-docker.sh
  8. 15
      src/crosscompile.sh
  9. 25
      src/lib/Cargo.toml
  10. 297
      src/lib/src/lib.rs
  11. 16
      src/main/Cargo.toml
  12. 97
      src/main/build.sh
  13. 214
      src/main/src/lib.rs
  14. 1
      src/rust-toolchain

4
.gitignore vendored

@ -0,0 +1,4 @@
/src/target
openssl*
.DS_Store
Cargo.lock

21
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.

22
README.md

@ -0,0 +1,22 @@
# Pirate Chain LiteWalletJNI Build System
Based on code from https://github.com/PirateNetwork/cordova-plugin-litewallet<br />
Adapted in July 2022 by Qortal dev team<br /><br />
### 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
```

13
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",
]

8
src/Cargo.toml

@ -0,0 +1,8 @@
[workspace]
members = [
"lib",
"main"
]
[profile.release]
debug = false

5
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

3
src/build-docker.sh

@ -0,0 +1,3 @@
#!/bin/bash
docker build -t piratejni .

15
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

25
src/lib/Cargo.toml

@ -0,0 +1,25 @@
[package]
name = "rustlib"
version = "1.0.0"
authors = ["Aditya Kulkarni <[email protected]>"]
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"

297
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(&params) {
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<RefCell<Option<Arc<LightClient>>>> = 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<LightClient>;
{
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<LightClient>;
{
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()
}

16
src/main/Cargo.toml

@ -0,0 +1,16 @@
[package]
name = "rust"
version = "1.0.0"
authors = ["Aditya Kulkarni <[email protected]>"]
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"]

97
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

214
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::<u64>().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()
}

1
src/rust-toolchain

@ -0,0 +1 @@
1.46.0
Loading…
Cancel
Save