mirror of
https://github.com/Qortal/pirate-litewalletjni.git
synced 2025-01-30 02:32:14 +00:00
Initial commit, originally based on code from https://github.com/PirateNetwork/cordova-plugin-litewallet
This commit is contained in:
commit
0a418e15df
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
/src/target
|
||||||
|
openssl*
|
||||||
|
.DS_Store
|
||||||
|
Cargo.lock
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -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
Normal file
22
README.md
Normal file
@ -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
Normal file
13
src/.cargo/config
Normal file
@ -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
Normal file
8
src/Cargo.toml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[workspace]
|
||||||
|
members = [
|
||||||
|
"lib",
|
||||||
|
"main"
|
||||||
|
]
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = false
|
5
src/Dockerfile
Normal file
5
src/Dockerfile
Normal file
@ -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
Executable file
3
src/build-docker.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
docker build -t piratejni .
|
15
src/crosscompile.sh
Executable file
15
src/crosscompile.sh
Executable file
@ -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
Normal file
25
src/lib/Cargo.toml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
[package]
|
||||||
|
name = "rustlib"
|
||||||
|
version = "1.0.0"
|
||||||
|
authors = ["Aditya Kulkarni <aditya@zecwallet.co>"]
|
||||||
|
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
Normal file
297
src/lib/src/lib.rs
Normal file
@ -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<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
Normal file
16
src/main/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
name = "rust"
|
||||||
|
version = "1.0.0"
|
||||||
|
authors = ["Aditya Kulkarni <aditya@zecwallet.co>"]
|
||||||
|
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
Executable file
97
src/main/build.sh
Executable file
@ -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
Normal file
214
src/main/src/lib.rs
Normal file
@ -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
Normal file
1
src/rust-toolchain
Normal file
@ -0,0 +1 @@
|
|||||||
|
1.46.0
|
Loading…
Reference in New Issue
Block a user