mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-android.git
synced 2026-06-14 00:31:03 +00:00
Initial commit: Pezkuwi Wallet Android
Security hardened release: - Code obfuscation enabled (minifyEnabled=true, shrinkResources=true) - Sensitive files excluded (google-services.json, keystores) - Branch.io key moved to BuildConfig placeholder - Updated dependencies: OkHttp 4.12.0, Gson 2.10.1, BouncyCastle 1.77 - Comprehensive ProGuard rules for crypto wallet - Navigation 2.7.7, Lifecycle 2.7.0, ConstraintLayout 2.1.4
This commit is contained in:
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,39 @@
|
||||
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
||||
|
||||
android {
|
||||
|
||||
ndkVersion "26.1.10909125"
|
||||
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
namespace 'io.novafoundation.nova.hydra_dx_math'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation kotlinDep
|
||||
implementation project(':common')
|
||||
|
||||
testImplementation jUnitDep
|
||||
|
||||
androidTestImplementation androidTestRunnerDep
|
||||
androidTestImplementation androidTestRulesDep
|
||||
androidTestImplementation androidJunitDep
|
||||
}
|
||||
|
||||
cargo {
|
||||
module = "rust/"
|
||||
libname = "hydra_dx_math_java"
|
||||
targets = ["arm", "arm64", "x86", "x86_64"]
|
||||
profile = "release"
|
||||
pythonCommand = "python3"
|
||||
}
|
||||
|
||||
tasks.matching { it.name.matches(/merge.*JniLibFolders/) }.configureEach {
|
||||
it.inputs.dir(new File(buildDir, "rustJniLibs/android"))
|
||||
it.dependsOn("cargoBuild")
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
.idea
|
||||
target
|
||||
Generated
+2916
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
||||
[package]
|
||||
authors = ['Novasama Technologies']
|
||||
edition = '2021'
|
||||
license = 'Apache 2.0'
|
||||
name = "hydra-dx-math-java"
|
||||
repository = 'https://github.com/nova-wallet/nova-wallet-android'
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.169", features = ["derive"] }
|
||||
serde_json = "1.0.100"
|
||||
serde-aux = "4.2.0"
|
||||
sp-arithmetic = { git = "https://github.com/galacticcouncil/polkadot-sdk", branch = "stable2409-patch6", default-features = false }
|
||||
hydra-dx-math = { git = "https://github.com/galacticcouncil/HydraDX-node", version="10.3.0"}
|
||||
jni = { version = "0.17.0", default-features = false }
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[lib]
|
||||
name = "hydra_dx_math_java"
|
||||
crate_type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
std = ["sp-arithmetic/std"]
|
||||
stableswap = []
|
||||
@@ -0,0 +1,732 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate core;
|
||||
extern crate hydra_dx_math;
|
||||
extern crate jni;
|
||||
extern crate serde;
|
||||
extern crate sp_arithmetic;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use hydra_dx_math::stableswap::types::AssetReserve;
|
||||
use jni::objects::{JClass, JString};
|
||||
use jni::sys::jint;
|
||||
use jni::JNIEnv;
|
||||
use serde::Deserialize;
|
||||
use sp_arithmetic::per_things::Permill;
|
||||
use serde_aux::prelude::*;
|
||||
|
||||
fn error() -> String {
|
||||
"-1".to_string()
|
||||
}
|
||||
|
||||
macro_rules! parse_into {
|
||||
($x:ty, $y:expr) => {{
|
||||
let r = if let Some(x) = $y.parse::<$x>().ok() {
|
||||
x
|
||||
} else {
|
||||
println!("Parse failed");
|
||||
return error();
|
||||
};
|
||||
r
|
||||
}};
|
||||
}
|
||||
|
||||
const D_ITERATIONS: u8 = 128;
|
||||
const Y_ITERATIONS: u8 = 64;
|
||||
|
||||
#[derive(Deserialize, Copy, Clone, Debug)]
|
||||
pub struct AssetBalance {
|
||||
asset_id: u32,
|
||||
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||
amount: u128,
|
||||
decimals: u8,
|
||||
}
|
||||
|
||||
impl From<&AssetBalance> for AssetReserve {
|
||||
fn from(value: &AssetBalance) -> Self {
|
||||
Self {
|
||||
amount: value.amount,
|
||||
decimals: value.decimals,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Copy, Clone, Debug)]
|
||||
pub struct AssetAmount {
|
||||
asset_id: u32,
|
||||
#[serde(deserialize_with = "deserialize_number_from_string")]
|
||||
amount: u128,
|
||||
}
|
||||
|
||||
// Tuple struct to apply per-field deserializers on u128s
|
||||
#[derive(Deserialize, Copy, Clone, Debug)]
|
||||
struct U128Pair(
|
||||
#[serde(deserialize_with = "deserialize_number_from_string")] u128,
|
||||
#[serde(deserialize_with = "deserialize_number_from_string")] u128,
|
||||
);
|
||||
|
||||
// Parse JSON like: [["0","0"],["1000000000000","500000000000"],["42","1337"]]
|
||||
fn parse_pairs(json: &str) -> Option<Vec<(u128, u128)>> {
|
||||
let v: serde_json::Result<Vec<U128Pair>> = serde_json::from_str(json);
|
||||
match v {
|
||||
Ok(vecp) => Some(vecp.into_iter().map(|p| (p.0, p.1)).collect()),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_str<'a>(jni: &'a JNIEnv<'a>, string: JString<'a>) -> String {
|
||||
jni.get_string(string).unwrap().to_str().unwrap().to_string()
|
||||
}
|
||||
|
||||
/* ---------------- STABLESWAP ---------------- */
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1out_1given_1in<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
reserves: JString,
|
||||
asset_in: jint,
|
||||
asset_out: jint,
|
||||
amount_in: JString,
|
||||
amplification: JString,
|
||||
fee: JString,
|
||||
pegs: JString,
|
||||
) -> JString<'a> {
|
||||
let reserves = get_str(&jni_env, reserves);
|
||||
let asset_in = asset_in as u32;
|
||||
let asset_out = asset_out as u32;
|
||||
let amount_in = get_str(&jni_env, amount_in);
|
||||
let amplification = get_str(&jni_env, amplification);
|
||||
let fee = get_str(&jni_env, fee);
|
||||
let pegs = get_str(&jni_env, pegs);
|
||||
|
||||
let out = calculate_out_given_in(
|
||||
reserves,
|
||||
asset_in,
|
||||
asset_out,
|
||||
amount_in,
|
||||
amplification,
|
||||
fee,
|
||||
pegs,
|
||||
);
|
||||
|
||||
jni_env.new_string(out).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_out_given_in(
|
||||
reserves: String,
|
||||
asset_in: u32,
|
||||
asset_out: u32,
|
||||
amount_in: String,
|
||||
amplification: String,
|
||||
fee: String,
|
||||
pegs: String,
|
||||
) -> String {
|
||||
let reserves: serde_json::Result<Vec<AssetBalance>> = serde_json::from_str(&reserves);
|
||||
if reserves.is_err() {
|
||||
return error();
|
||||
}
|
||||
let mut reserves = reserves.unwrap();
|
||||
reserves.sort_by_key(|v| v.asset_id);
|
||||
|
||||
let idx_in = reserves.iter().position(|v| v.asset_id == asset_in);
|
||||
let idx_out = reserves.iter().position(|v| v.asset_id == asset_out);
|
||||
|
||||
if idx_in.is_none() || idx_out.is_none() {
|
||||
return error();
|
||||
}
|
||||
|
||||
let amount_in = parse_into!(u128, amount_in);
|
||||
let amplification = parse_into!(u128, amplification);
|
||||
let fee = Permill::from_float(parse_into!(f64, fee));
|
||||
let balances: Vec<AssetReserve> = reserves.iter().map(|v| v.into()).collect();
|
||||
|
||||
// Parse 7th param
|
||||
let pairs = match parse_pairs(&pegs) {
|
||||
Some(p) => p,
|
||||
None => return error(),
|
||||
};
|
||||
|
||||
let result = hydra_dx_math::stableswap::calculate_out_given_in_with_fee::<D_ITERATIONS, Y_ITERATIONS>(
|
||||
&balances,
|
||||
idx_in.unwrap(),
|
||||
idx_out.unwrap(),
|
||||
amount_in,
|
||||
amplification,
|
||||
fee,
|
||||
&pairs,
|
||||
);
|
||||
|
||||
if let Some(r) = result {
|
||||
r.0.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1in_1given_1out<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
reserves: JString,
|
||||
asset_in: jint,
|
||||
asset_out: jint,
|
||||
amount_in: JString,
|
||||
amplification: JString,
|
||||
fee: JString,
|
||||
pegs: JString,
|
||||
) -> JString<'a> {
|
||||
let reserves = get_str(&jni_env, reserves);
|
||||
let asset_in = asset_in as u32;
|
||||
let asset_out = asset_out as u32;
|
||||
let amount_in = get_str(&jni_env, amount_in);
|
||||
let amplification = get_str(&jni_env, amplification);
|
||||
let fee = get_str(&jni_env, fee);
|
||||
let pegs = get_str(&jni_env, pegs);
|
||||
|
||||
let result = calculate_in_given_out(
|
||||
reserves,
|
||||
asset_in,
|
||||
asset_out,
|
||||
amount_in,
|
||||
amplification,
|
||||
fee,
|
||||
pegs,
|
||||
);
|
||||
|
||||
jni_env.new_string(result).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_in_given_out(
|
||||
reserves: String,
|
||||
asset_in: u32,
|
||||
asset_out: u32,
|
||||
amount_out: String,
|
||||
amplification: String,
|
||||
fee: String,
|
||||
pegs: String,
|
||||
) -> String {
|
||||
let reserves: serde_json::Result<Vec<AssetBalance>> = serde_json::from_str(&reserves);
|
||||
if reserves.is_err() {
|
||||
return error();
|
||||
}
|
||||
let mut reserves = reserves.unwrap();
|
||||
reserves.sort_by_key(|v| v.asset_id);
|
||||
|
||||
let idx_in = reserves.iter().position(|v| v.asset_id == asset_in);
|
||||
let idx_out = reserves.iter().position(|v| v.asset_id == asset_out);
|
||||
|
||||
if idx_in.is_none() || idx_out.is_none() {
|
||||
return error();
|
||||
}
|
||||
|
||||
let amount_out = parse_into!(u128, amount_out);
|
||||
let amplification = parse_into!(u128, amplification);
|
||||
let fee = Permill::from_float(parse_into!(f64, fee));
|
||||
|
||||
let balances: Vec<AssetReserve> = reserves.iter().map(|v| v.into()).collect();
|
||||
|
||||
// Parse 7th param
|
||||
let pairs = match parse_pairs(&pegs) {
|
||||
Some(p) => p,
|
||||
None => return error(),
|
||||
};
|
||||
|
||||
let result =
|
||||
hydra_dx_math::stableswap::calculate_in_given_out_with_fee::<D_ITERATIONS, Y_ITERATIONS>(
|
||||
&balances,
|
||||
idx_in.unwrap(),
|
||||
idx_out.unwrap(),
|
||||
amount_out,
|
||||
amplification,
|
||||
fee,
|
||||
&pairs,
|
||||
);
|
||||
|
||||
if let Some(r) = result {
|
||||
r.0.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1amplification<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
initial_amplification: JString,
|
||||
final_amplification: JString,
|
||||
initial_block: JString,
|
||||
final_block: JString,
|
||||
current_block: JString,
|
||||
) -> JString<'a> {
|
||||
let initial_amplification = get_str(&jni_env, initial_amplification);
|
||||
let final_amplification = get_str(&jni_env, final_amplification);
|
||||
let initial_block = get_str(&jni_env, initial_block);
|
||||
let final_block = get_str(&jni_env, final_block);
|
||||
let current_block = get_str(&jni_env, current_block);
|
||||
|
||||
let result = calculate_amplification(
|
||||
initial_amplification,
|
||||
final_amplification,
|
||||
initial_block,
|
||||
final_block,
|
||||
current_block,
|
||||
);
|
||||
|
||||
jni_env.new_string(result).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_amplification(
|
||||
initial_amplification: String,
|
||||
final_amplification: String,
|
||||
initial_block: String,
|
||||
final_block: String,
|
||||
current_block: String,
|
||||
) -> String {
|
||||
let initial_amplification = parse_into!(u128, initial_amplification);
|
||||
let final_amplification = parse_into!(u128, final_amplification);
|
||||
let initial_block = parse_into!(u128, initial_block);
|
||||
let final_block = parse_into!(u128, final_block);
|
||||
let current_block = parse_into!(u128, current_block);
|
||||
|
||||
hydra_dx_math::stableswap::calculate_amplification(
|
||||
initial_amplification,
|
||||
final_amplification,
|
||||
initial_block,
|
||||
final_block,
|
||||
current_block,
|
||||
)
|
||||
.to_string()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1shares<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
reserves: JString,
|
||||
assets: JString,
|
||||
amplification: JString,
|
||||
share_issuance: JString,
|
||||
fee: JString,
|
||||
pegs: JString,
|
||||
) -> JString<'a> {
|
||||
let reserves = get_str(&jni_env, reserves);
|
||||
let assets = get_str(&jni_env, assets);
|
||||
let amplification = get_str(&jni_env, amplification);
|
||||
let share_issuance = get_str(&jni_env, share_issuance);
|
||||
let fee = get_str(&jni_env, fee);
|
||||
let pegs = get_str(&jni_env, pegs);
|
||||
|
||||
let result = calculate_shares(reserves, assets, amplification, share_issuance, fee, pegs);
|
||||
|
||||
jni_env.new_string(result).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_shares(
|
||||
reserves: String,
|
||||
assets: String,
|
||||
amplification: String,
|
||||
share_issuance: String,
|
||||
fee: String,
|
||||
pegs: String,
|
||||
) -> String {
|
||||
let reserves: serde_json::Result<Vec<AssetBalance>> = serde_json::from_str(&reserves);
|
||||
if reserves.is_err() {
|
||||
return error();
|
||||
}
|
||||
let mut reserves = reserves.unwrap();
|
||||
reserves.sort_by_key(|v| v.asset_id);
|
||||
|
||||
let assets: serde_json::Result<Vec<AssetAmount>> = serde_json::from_str(&assets);
|
||||
if assets.is_err() {
|
||||
return error();
|
||||
}
|
||||
let assets = assets.unwrap();
|
||||
if assets.len() > reserves.len() {
|
||||
return error();
|
||||
}
|
||||
|
||||
let mut updated_reserves = reserves.clone();
|
||||
|
||||
let mut liquidity: HashMap<u32, u128> = HashMap::new();
|
||||
for a in assets.iter() {
|
||||
let r = liquidity.insert(a.asset_id, a.amount);
|
||||
if r.is_some() {
|
||||
return error();
|
||||
}
|
||||
}
|
||||
for reserve in updated_reserves.iter_mut() {
|
||||
if let Some(v) = liquidity.get(&reserve.asset_id) {
|
||||
reserve.amount += v;
|
||||
}
|
||||
}
|
||||
let balances: Vec<AssetReserve> = reserves.iter().map(|v| v.into()).collect();
|
||||
let updated_balances: Vec<AssetReserve> = updated_reserves.iter().map(|v| v.into()).collect();
|
||||
let amplification = parse_into!(u128, amplification);
|
||||
let issuance = parse_into!(u128, share_issuance);
|
||||
let fee = Permill::from_float(parse_into!(f64, fee));
|
||||
|
||||
let pairs = match parse_pairs(&pegs) {
|
||||
Some(p) => p,
|
||||
None => return error(),
|
||||
};
|
||||
|
||||
let result = hydra_dx_math::stableswap::calculate_shares::<D_ITERATIONS>(
|
||||
&balances,
|
||||
&updated_balances,
|
||||
amplification,
|
||||
issuance,
|
||||
fee,
|
||||
&pairs,
|
||||
);
|
||||
|
||||
if let Some(r) = result {
|
||||
r.0.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1shares_1for_1amount<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
reserves: JString,
|
||||
asset_in: jint,
|
||||
amount: JString,
|
||||
amplification: JString,
|
||||
share_issuance: JString,
|
||||
fee: JString,
|
||||
pegs: JString,
|
||||
) -> JString<'a> {
|
||||
let reserves = get_str(&jni_env, reserves);
|
||||
let asset_in = asset_in as u32;
|
||||
let amount = get_str(&jni_env, amount);
|
||||
let amplification = get_str(&jni_env, amplification);
|
||||
let share_issuance = get_str(&jni_env, share_issuance);
|
||||
let fee = get_str(&jni_env, fee);
|
||||
let pegs = get_str(&jni_env, pegs);
|
||||
|
||||
let result = calculate_shares_for_amount(
|
||||
reserves,
|
||||
asset_in,
|
||||
amount,
|
||||
amplification,
|
||||
share_issuance,
|
||||
fee,
|
||||
pegs,
|
||||
);
|
||||
|
||||
jni_env.new_string(result).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_shares_for_amount(
|
||||
reserves: String,
|
||||
asset_in: u32,
|
||||
amount: String,
|
||||
amplification: String,
|
||||
share_issuance: String,
|
||||
fee: String,
|
||||
pegs: String,
|
||||
) -> String {
|
||||
let reserves: serde_json::Result<Vec<AssetBalance>> = serde_json::from_str(&reserves);
|
||||
if reserves.is_err() {
|
||||
return error();
|
||||
}
|
||||
let mut reserves = reserves.unwrap();
|
||||
reserves.sort_by_key(|v| v.asset_id);
|
||||
let idx_in = reserves.iter().position(|v| v.asset_id == asset_in);
|
||||
if idx_in.is_none() {
|
||||
return error();
|
||||
}
|
||||
let amount_in = parse_into!(u128, amount);
|
||||
let balances: Vec<AssetReserve> = reserves.iter().map(|v| v.into()).collect();
|
||||
let amplification = parse_into!(u128, amplification);
|
||||
let issuance = parse_into!(u128, share_issuance);
|
||||
let fee = Permill::from_float(parse_into!(f64, fee));
|
||||
|
||||
// Parse 7th param
|
||||
let pairs = match parse_pairs(&pegs) {
|
||||
Some(p) => p,
|
||||
None => return error(),
|
||||
};
|
||||
|
||||
let result = hydra_dx_math::stableswap::calculate_shares_for_amount::<D_ITERATIONS>(
|
||||
&balances,
|
||||
idx_in.unwrap(),
|
||||
amount_in,
|
||||
amplification,
|
||||
issuance,
|
||||
fee,
|
||||
&pairs,
|
||||
);
|
||||
|
||||
if let Some(r) = result {
|
||||
r.0.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1add_1one_1asset<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
reserves: JString,
|
||||
shares: JString,
|
||||
asset_in: jint,
|
||||
amplification: JString,
|
||||
share_issuance: JString,
|
||||
fee: JString,
|
||||
pegs: JString,
|
||||
) -> JString<'a> {
|
||||
let reserves = get_str(&jni_env, reserves);
|
||||
let shares = get_str(&jni_env, shares);
|
||||
let asset_in = asset_in as u32;
|
||||
let amplification = get_str(&jni_env, amplification);
|
||||
let share_issuance = get_str(&jni_env, share_issuance);
|
||||
let fee = get_str(&jni_env, fee);
|
||||
let pegs = get_str(&jni_env, pegs);
|
||||
|
||||
let result = calculate_add_one_asset(
|
||||
reserves,
|
||||
shares,
|
||||
asset_in,
|
||||
amplification,
|
||||
share_issuance,
|
||||
fee,
|
||||
pegs,
|
||||
);
|
||||
|
||||
jni_env.new_string(result).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_add_one_asset(
|
||||
reserves: String,
|
||||
shares: String,
|
||||
asset_in: u32,
|
||||
amplification: String,
|
||||
share_issuance: String,
|
||||
fee: String,
|
||||
pegs: String,
|
||||
) -> String {
|
||||
let reserves: serde_json::Result<Vec<AssetBalance>> = serde_json::from_str(&reserves);
|
||||
if reserves.is_err() {
|
||||
return error();
|
||||
}
|
||||
let mut reserves = reserves.unwrap();
|
||||
reserves.sort_by_key(|v| v.asset_id);
|
||||
let idx_in = reserves.iter().position(|v| v.asset_id == asset_in);
|
||||
if idx_in.is_none() {
|
||||
return error();
|
||||
}
|
||||
|
||||
let balances: Vec<AssetReserve> = reserves.iter().map(|v| v.into()).collect();
|
||||
let shares = parse_into!(u128, shares);
|
||||
let amplification = parse_into!(u128, amplification);
|
||||
let issuance = parse_into!(u128, share_issuance);
|
||||
let fee = Permill::from_float(parse_into!(f64, fee));
|
||||
|
||||
let pairs = match parse_pairs(&pegs) {
|
||||
Some(p) => p,
|
||||
None => return error(),
|
||||
};
|
||||
|
||||
let result = hydra_dx_math::stableswap::calculate_add_one_asset::<D_ITERATIONS, Y_ITERATIONS>(
|
||||
&balances,
|
||||
shares,
|
||||
idx_in.unwrap(),
|
||||
issuance,
|
||||
amplification,
|
||||
fee,
|
||||
&pairs,
|
||||
);
|
||||
|
||||
if let Some(r) = result {
|
||||
r.0.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_stableswap_StableSwapMathBridge_calculate_1liquidity_1out_1one_1asset<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
reserves: JString,
|
||||
shares: JString,
|
||||
asset_out: jint,
|
||||
amplification: JString,
|
||||
share_issuance: JString,
|
||||
withdraw_fee: JString,
|
||||
pegs: JString,
|
||||
) -> JString<'a> {
|
||||
let reserves = get_str(&jni_env, reserves);
|
||||
let shares = get_str(&jni_env, shares);
|
||||
let asset_out = asset_out as u32;
|
||||
let amplification = get_str(&jni_env, amplification);
|
||||
let share_issuance = get_str(&jni_env, share_issuance);
|
||||
let withdraw_fee = get_str(&jni_env, withdraw_fee);
|
||||
let pegs = get_str(&jni_env, pegs);
|
||||
|
||||
let result = calculate_liquidity_out_one_asset(
|
||||
reserves,
|
||||
shares,
|
||||
asset_out,
|
||||
amplification,
|
||||
share_issuance,
|
||||
withdraw_fee,
|
||||
pegs,
|
||||
);
|
||||
|
||||
jni_env.new_string(result).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_liquidity_out_one_asset(
|
||||
reserves: String,
|
||||
shares: String,
|
||||
asset_out: u32,
|
||||
amplification: String,
|
||||
share_issuance: String,
|
||||
withdraw_fee: String,
|
||||
pegs: String,
|
||||
) -> String {
|
||||
let reserves: serde_json::Result<Vec<AssetBalance>> = serde_json::from_str(&reserves);
|
||||
if reserves.is_err() {
|
||||
return error();
|
||||
}
|
||||
let mut reserves = reserves.unwrap();
|
||||
reserves.sort_by_key(|v| v.asset_id);
|
||||
|
||||
let idx_out = reserves.iter().position(|v| v.asset_id == asset_out);
|
||||
if idx_out.is_none() {
|
||||
println!("idx_out error");
|
||||
return error();
|
||||
}
|
||||
|
||||
let shares_out = parse_into!(u128, shares);
|
||||
let amplification = parse_into!(u128, amplification);
|
||||
let issuance = parse_into!(u128, share_issuance);
|
||||
let fee = Permill::from_float(parse_into!(f64, withdraw_fee));
|
||||
|
||||
let balances: Vec<AssetReserve> = reserves.iter().map(|v| v.into()).collect();
|
||||
|
||||
let pairs = match parse_pairs(&pegs) {
|
||||
Some(p) => p,
|
||||
None => { println!("parse_pairs error"); return error(); },
|
||||
};
|
||||
|
||||
let result = hydra_dx_math::stableswap::calculate_withdraw_one_asset::<D_ITERATIONS, Y_ITERATIONS>(
|
||||
&balances,
|
||||
shares_out,
|
||||
idx_out.unwrap(),
|
||||
issuance,
|
||||
amplification,
|
||||
fee,
|
||||
&pairs,
|
||||
);
|
||||
|
||||
if let Some(r) = result {
|
||||
r.0.to_string()
|
||||
} else {
|
||||
println!("final result error");
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------- XYK ---------------------- */
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_xyk_HYKSwapMathBridge_calculate_1out_1given_1in<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
balance_in: JString,
|
||||
balance_out: JString,
|
||||
amount_in: JString,
|
||||
) -> JString<'a> {
|
||||
let balance_in: String = get_str(&jni_env, balance_in);
|
||||
let balance_out: String = get_str(&jni_env, balance_out);
|
||||
let amount_in: String = get_str(&jni_env, amount_in);
|
||||
|
||||
let out = xyk_calculate_out_given_in(balance_in, balance_out, amount_in);
|
||||
|
||||
jni_env.new_string(out).unwrap()
|
||||
}
|
||||
|
||||
fn xyk_calculate_out_given_in(balance_in: String, balance_out: String, amount_in: String) -> String {
|
||||
let balance_in = parse_into!(u128, balance_in);
|
||||
let balance_out = parse_into!(u128, balance_out);
|
||||
let amount_in = parse_into!(u128, amount_in);
|
||||
|
||||
let result = hydra_dx_math::xyk::calculate_out_given_in(balance_in, balance_out, amount_in);
|
||||
|
||||
if let Ok(r) = result {
|
||||
r.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_xyk_HYKSwapMathBridge_calculate_1in_1given_1out<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
balance_in: JString,
|
||||
balance_out: JString,
|
||||
amount_in: JString,
|
||||
) -> JString<'a> {
|
||||
let balance_in: String = get_str(&jni_env, balance_in);
|
||||
let balance_out: String = get_str(&jni_env, balance_out);
|
||||
let amount_in: String = get_str(&jni_env, amount_in);
|
||||
|
||||
let out = xyk_calculate_in_given_out(balance_in, balance_out, amount_in);
|
||||
|
||||
jni_env.new_string(out).unwrap()
|
||||
}
|
||||
|
||||
fn xyk_calculate_in_given_out(balance_in: String, balance_out: String, amount_out: String) -> String {
|
||||
let balance_in = parse_into!(u128, balance_in);
|
||||
let balance_out = parse_into!(u128, balance_out);
|
||||
let amount_out = parse_into!(u128, amount_out);
|
||||
|
||||
let result = hydra_dx_math::xyk::calculate_in_given_out(balance_out, balance_in, amount_out);
|
||||
|
||||
if let Ok(r) = result {
|
||||
r.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn Java_io_novafoundation_nova_hydra_1dx_1math_xyk_HYKSwapMathBridge_calculate_1pool_1trade_1fee<'a>(
|
||||
jni_env: JNIEnv<'a>,
|
||||
_: JClass,
|
||||
amount: JString,
|
||||
fee_nominator: JString,
|
||||
fee_denominator: JString,
|
||||
) -> JString<'a> {
|
||||
let amount: String = get_str(&jni_env, amount);
|
||||
let fee_nominator: String = get_str(&jni_env, fee_nominator);
|
||||
let fee_denominator: String = get_str(&jni_env, fee_denominator);
|
||||
|
||||
let out = calculate_pool_trade_fee(amount, fee_nominator, fee_denominator);
|
||||
|
||||
jni_env.new_string(out).unwrap()
|
||||
}
|
||||
|
||||
fn calculate_pool_trade_fee(amount: String, fee_nominator: String, fee_denominator: String) -> String {
|
||||
let amount = parse_into!(u128, amount);
|
||||
let fee_nominator = parse_into!(u32, fee_nominator);
|
||||
let fee_denominator = parse_into!(u32, fee_denominator);
|
||||
|
||||
let result = hydra_dx_math::fee::calculate_pool_trade_fee(amount, (fee_nominator, fee_denominator));
|
||||
|
||||
if let Some(r) = result {
|
||||
r.to_string()
|
||||
} else {
|
||||
error()
|
||||
}
|
||||
}
|
||||
+279
@@ -0,0 +1,279 @@
|
||||
package io.novafoundation.nova.hydra_dx_math.stableswap
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNotEquals
|
||||
import org.junit.Ignore
|
||||
import org.junit.Test
|
||||
|
||||
class StableSwapTest {
|
||||
|
||||
@Test
|
||||
fun shouldCalculateOutGivenIn() {
|
||||
val data = """
|
||||
[{
|
||||
"asset_id": 1,
|
||||
"amount": "1000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 0,
|
||||
"amount": "1000000000000",
|
||||
"decimals": 12
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_out_given_in(
|
||||
data,
|
||||
0,
|
||||
1,
|
||||
"1000000000",
|
||||
"1",
|
||||
"0",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("999500248", result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldCalculateInGiveOut() {
|
||||
val data = """
|
||||
[{
|
||||
"asset_id": 1,
|
||||
"amount": "1000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 0,
|
||||
"amount": "1000000000000",
|
||||
"decimals": 12
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_in_given_out(
|
||||
data,
|
||||
0,
|
||||
1,
|
||||
"1000000000",
|
||||
"1",
|
||||
"0",
|
||||
""
|
||||
)
|
||||
|
||||
assertNotEquals("-1", result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldCalculateAmplification() {
|
||||
val result = StableSwapMathBridge.calculate_amplification("10", "10", "0", "100", "50")
|
||||
|
||||
assertEquals("10", result)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldCalculateShares() {
|
||||
val data = """
|
||||
[{
|
||||
"asset_id": 0,
|
||||
"amount":"90000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 1,
|
||||
"amount": "5000000000000000000000",
|
||||
"decimals": 12
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
val assets = """
|
||||
[{"asset_id":1,"amount":"43000000000000000000"}]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_shares(
|
||||
data,
|
||||
assets,
|
||||
"1000",
|
||||
"64839594451719860",
|
||||
"0",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("371541351762585", result.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldCalculateSharesForAmount() {
|
||||
val data = """
|
||||
[
|
||||
{
|
||||
"asset_id": 0,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 1,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 2,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 3,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 4,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_shares_for_amount(
|
||||
data,
|
||||
0,
|
||||
"100000000000000",
|
||||
"100",
|
||||
"20000000000000000000000",
|
||||
"0",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("40001593768209443008", result.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore("The test fails with last digit being 0 instead of 1. We need to check why it happens later")
|
||||
fun shouldCalculateAddOneAsset() {
|
||||
val data = """
|
||||
[
|
||||
{
|
||||
"asset_id": 0,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 1,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 2,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 3,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 4,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_add_one_asset(
|
||||
data,
|
||||
"399850144492663029649",
|
||||
2,
|
||||
"100",
|
||||
"20000000000000000000000",
|
||||
"0",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("1000000000000001", result.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun shouldcalculateLiquidityOutOneAsset() {
|
||||
val data = """
|
||||
[
|
||||
{
|
||||
"asset_id": 0,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 1,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 2,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 3,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
},
|
||||
{
|
||||
"asset_id": 4,
|
||||
"amount": "10000000000000000",
|
||||
"decimals": 12
|
||||
}
|
||||
]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_liquidity_out_one_asset(
|
||||
data,
|
||||
"40001593768209443008",
|
||||
0,
|
||||
"100",
|
||||
"20000000000000000000000",
|
||||
"0",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("99999999999999", result.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun failingCase() {
|
||||
val data = """
|
||||
[{"amount":"2246975221087","decimals":6,"asset_id":10},{"amount":"2256486088023","decimals":6,"asset_id":22}]
|
||||
"""
|
||||
|
||||
val result = StableSwapMathBridge.calculate_liquidity_out_one_asset(
|
||||
data,
|
||||
"1000000000",
|
||||
10,
|
||||
"100",
|
||||
"4502091550542833181457210",
|
||||
"0.00040",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("99999999999999", result.toString())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun failingCase2() {
|
||||
val data = """
|
||||
[{"amount":"505342304916","decimals":6,"asset_id":10},{"amount":"368030436758902944990436","decimals":18,"asset_id":18},{"amount":"410374848833","decimals":6,"asset_id":21},{"amount":"0","decimals":6,"asset_id":23}] """
|
||||
|
||||
val result = StableSwapMathBridge.calculate_shares_for_amount(
|
||||
data,
|
||||
10,
|
||||
"10",
|
||||
"320",
|
||||
"1662219218861236418723363",
|
||||
"0.00040",
|
||||
""
|
||||
)
|
||||
|
||||
assertEquals("99999999999999", result.toString())
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package io.novafoundation.nova.hydra_dx_math
|
||||
|
||||
import io.novafoundation.nova.common.utils.atLeastZero
|
||||
import java.math.BigInteger
|
||||
|
||||
object HydraDxMathConversions {
|
||||
|
||||
fun String.fromBridgeResultToBalance(): BigInteger? {
|
||||
return if (this == "-1") null else toBigInteger().atLeastZero()
|
||||
}
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package io.novafoundation.nova.hydra_dx_math.stableswap;
|
||||
|
||||
public class StableSwapMathBridge {
|
||||
|
||||
static {
|
||||
System.loadLibrary("hydra_dx_math_java");
|
||||
}
|
||||
|
||||
public static native String calculate_out_given_in(
|
||||
String reserves,
|
||||
int asset_in,
|
||||
int asset_out,
|
||||
String amount_in,
|
||||
String amplification,
|
||||
String fee,
|
||||
String pegs
|
||||
);
|
||||
|
||||
public static native String calculate_in_given_out(
|
||||
String reserves,
|
||||
int asset_in,
|
||||
int asset_out,
|
||||
String amount_out,
|
||||
String amplification,
|
||||
String fee,
|
||||
String pegs
|
||||
);
|
||||
|
||||
public static native String calculate_amplification(
|
||||
String initial_amplification,
|
||||
String final_amplification,
|
||||
String initial_block,
|
||||
String final_block,
|
||||
String current_block
|
||||
);
|
||||
|
||||
public static native String calculate_shares(
|
||||
String reserves,
|
||||
String assets,
|
||||
String amplification,
|
||||
String share_issuance,
|
||||
String fee,
|
||||
String pegs
|
||||
);
|
||||
|
||||
public static native String calculate_shares_for_amount(
|
||||
String reserves,
|
||||
int asset_in,
|
||||
String amount,
|
||||
String amplification,
|
||||
String share_issuance,
|
||||
String fee,
|
||||
String pegs
|
||||
);
|
||||
|
||||
public static native String calculate_add_one_asset(
|
||||
String reserves,
|
||||
String shares,
|
||||
int asset_in,
|
||||
String amplification,
|
||||
String share_issuance,
|
||||
String fee,
|
||||
String pegs
|
||||
);
|
||||
|
||||
public static native String calculate_liquidity_out_one_asset(
|
||||
String reserves,
|
||||
String shares,
|
||||
int asset_out,
|
||||
String amplification,
|
||||
String share_issuance,
|
||||
String withdraw_fee,
|
||||
String pegs
|
||||
);
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package io.novafoundation.nova.hydra_dx_math.xyk;
|
||||
|
||||
public class HYKSwapMathBridge {
|
||||
|
||||
static {
|
||||
System.loadLibrary("hydra_dx_math_java");
|
||||
}
|
||||
|
||||
public static native String calculate_out_given_in(
|
||||
String balanceIn,
|
||||
String balanceOut,
|
||||
String amountIn
|
||||
);
|
||||
|
||||
public static native String calculate_in_given_out(
|
||||
String balanceIn,
|
||||
String balanceOut,
|
||||
String amountOut
|
||||
);
|
||||
|
||||
public static native String calculate_pool_trade_fee(
|
||||
String amount,
|
||||
String feeNumerator,
|
||||
String feeDenominator
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,38 @@
|
||||
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
||||
|
||||
android {
|
||||
namespace 'io.novafoundation.nova.metadata_shortener'
|
||||
|
||||
ndkVersion "26.1.10909125"
|
||||
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation kotlinDep
|
||||
|
||||
testImplementation jUnitDep
|
||||
|
||||
androidTestImplementation androidTestRunnerDep
|
||||
androidTestImplementation androidTestRulesDep
|
||||
androidTestImplementation androidJunitDep
|
||||
}
|
||||
|
||||
cargo {
|
||||
module = "rust/"
|
||||
libname = "metadata_shortener_java"
|
||||
targets = ["arm", "arm64", "x86", "x86_64"]
|
||||
profile = "release"
|
||||
pythonCommand = "python3"
|
||||
}
|
||||
|
||||
tasks.matching { it.name.matches(/merge.*JniLibFolders/) }.configureEach {
|
||||
it.inputs.dir(new File(buildDir, "rustJniLibs/android"))
|
||||
it.dependsOn("cargoBuild")
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,2 @@
|
||||
.idea
|
||||
target
|
||||
+535
@@ -0,0 +1,535 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "array-bytes"
|
||||
version = "6.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5d5dde061bd34119e902bbb2d9b90c5692635cf59fb91d582c2b68043f1b8293"
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711"
|
||||
|
||||
[[package]]
|
||||
name = "bitvec"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
|
||||
dependencies = [
|
||||
"funty",
|
||||
"radium",
|
||||
"tap",
|
||||
"wyz",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blake3"
|
||||
version = "1.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52"
|
||||
dependencies = [
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"constant_time_eq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byte-slice-cast"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3ac9f8b63eca6fd385229b3675f6cc0dc5c8a5c8a54a59d4f52ffd670d87b0c"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.99"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "constant_time_eq"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2"
|
||||
|
||||
[[package]]
|
||||
name = "derive_more"
|
||||
version = "0.99.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
|
||||
|
||||
[[package]]
|
||||
name = "error-chain"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d2f06b9cac1506ece98fe3231e3cc9c4410ec3d5b1f24ae1c8946f0742cdefc"
|
||||
dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "frame-metadata"
|
||||
version = "16.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87cf1549fba25a6fcac22785b61698317d958e96cac72a59102ea45b9ae64692"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"parity-scale-codec",
|
||||
"scale-info",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "funty"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
|
||||
[[package]]
|
||||
name = "impl-trait-for-tuples"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11d7a9f6330b71fea57921c9b61c47ee6e84f72d394754eff6163ae67e7395eb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "36bcc950632e48b86da402c5c077590583da5ac0d480103611d5374e7c967a3c"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"combine",
|
||||
"error-chain",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d0d8b92cd8358e8d229c11df9358decae64d137c5be540952c5ca7b25aea768"
|
||||
|
||||
[[package]]
|
||||
name = "merkleized-metadata"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/Zondax/merkleized-metadata?rev=cd1363a2c4702abf34fcc461055f0059b3c32bec#cd1363a2c4702abf34fcc461055f0059b3c32bec"
|
||||
dependencies = [
|
||||
"array-bytes",
|
||||
"blake3",
|
||||
"frame-metadata",
|
||||
"parity-scale-codec",
|
||||
"scale-decode",
|
||||
"scale-info",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "metadata-shortener-java"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"array-bytes",
|
||||
"frame-metadata",
|
||||
"jni",
|
||||
"merkleized-metadata",
|
||||
"parity-scale-codec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-scale-codec"
|
||||
version = "3.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "306800abfa29c7f16596b5970a588435e3d5b3149683d00c12b699cc19f895ee"
|
||||
dependencies = [
|
||||
"arrayvec",
|
||||
"bitvec",
|
||||
"byte-slice-cast",
|
||||
"impl-trait-for-tuples",
|
||||
"parity-scale-codec-derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parity-scale-codec-derive"
|
||||
version = "3.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d830939c76d294956402033aee57a6da7b438f2294eb94864c37b0569053a42c"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-crate"
|
||||
version = "3.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284"
|
||||
dependencies = [
|
||||
"toml_edit",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.85"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "radium"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scale-bits"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e57b1e7f6b65ed1f04e79a85a57d755ad56d76fdf1e9bddcc9ae14f71fcdcf54"
|
||||
dependencies = [
|
||||
"parity-scale-codec",
|
||||
"scale-type-resolver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scale-decode"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7e10e0d345101a013ca3af62c2d44d20213d543cc64d96080c68d931e54360c5"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"parity-scale-codec",
|
||||
"scale-bits",
|
||||
"scale-type-resolver",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scale-info"
|
||||
version = "2.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eca070c12893629e2cc820a9761bedf6ce1dcddc9852984d1dc734b8bd9bd024"
|
||||
dependencies = [
|
||||
"bitvec",
|
||||
"cfg-if",
|
||||
"derive_more",
|
||||
"parity-scale-codec",
|
||||
"scale-info-derive",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scale-info-derive"
|
||||
version = "2.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d35494501194174bda522a32605929eefc9ecf7e0a326c26db1fdd85881eb62"
|
||||
dependencies = [
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scale-type-resolver"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0cded6518aa0bd6c1be2b88ac81bf7044992f0f154bfbabd5ad34f43512abcb"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.203"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.203"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.66",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.13.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.66"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tap"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf"
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b"
|
||||
dependencies = [
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wyz"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
|
||||
dependencies = [
|
||||
"tap",
|
||||
]
|
||||
@@ -0,0 +1,23 @@
|
||||
[package]
|
||||
authors = ['Novasama Technologies']
|
||||
edition = '2021'
|
||||
license = 'Apache 2.0'
|
||||
name = "metadata-shortener-java"
|
||||
repository = 'https://github.com/nova-wallet/nova-wallet-android'
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
array-bytes = "6.2.2"
|
||||
merkleized-metadata = { git = "https://github.com/Zondax/merkleized-metadata", default-features = false, rev = "cd1363a2c4702abf34fcc461055f0059b3c32bec" }
|
||||
jni = { version = "0.17.0", default-features = false }
|
||||
frame-metadata = { version = "16.0.0", features = [ "current" ] }
|
||||
codec = { package = "parity-scale-codec", version = "3.6.9", features = [ "derive" ] }
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[lib]
|
||||
name = "metadata_shortener_java"
|
||||
crate_type = ["cdylib"]
|
||||
@@ -0,0 +1,214 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
extern crate core;
|
||||
extern crate jni;
|
||||
extern crate merkleized_metadata;
|
||||
|
||||
use codec::{Decode, Encode};
|
||||
use frame_metadata::{RuntimeMetadataPrefixed, OpaqueMetadata, RuntimeMetadata};
|
||||
use jni::{errors::Result as JniResult, sys::jint};
|
||||
use jni::objects::{JClass, JString};
|
||||
use jni::sys::jbyteArray;
|
||||
use jni::JNIEnv;
|
||||
use merkleized_metadata::{generate_metadata_digest, generate_proof_for_extrinsic_parts, ExtraInfo, SignedExtrinsicData, FrameMetadataPrepared, Proof, ExtrinsicMetadata};
|
||||
use std::ptr;
|
||||
|
||||
#[derive(Encode)]
|
||||
pub struct MetadataProof {
|
||||
proof: Proof,
|
||||
extrinsic: ExtrinsicMetadata,
|
||||
extra_info: ExtraInfo,
|
||||
}
|
||||
|
||||
macro_rules! r#try_or_throw {
|
||||
($jni_env: ident, $expr:expr, $ret: expr) => {
|
||||
match $expr {
|
||||
JniResult::Ok(val) => val,
|
||||
JniResult::Err(err) => {
|
||||
$jni_env
|
||||
.throw_new("java/lang/Exception", err.description())
|
||||
.unwrap();
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
};
|
||||
($expr:expr,) => {
|
||||
$crate::r#try!($expr)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! r#try_or_throw_null {
|
||||
($jni_env: ident, $expr:expr) => {
|
||||
try_or_throw!($jni_env, $expr, ptr::null_mut())
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn Java_io_novafoundation_nova_metadata_1shortener_MetadataShortener_generate_1extrinsic_1proof(
|
||||
jni_env: JNIEnv,
|
||||
_: JClass,
|
||||
call: jbyteArray,
|
||||
signed_extras: jbyteArray,
|
||||
additional_signed: jbyteArray,
|
||||
metadata: jbyteArray,
|
||||
spec_version: jint,
|
||||
spec_name: JString,
|
||||
base58_prefix: jint,
|
||||
decimals: jint,
|
||||
token_symbol: JString,
|
||||
) -> jbyteArray {
|
||||
let Some(metadata) = decode_metadata(&jni_env, metadata) else {
|
||||
return ptr::null_mut();
|
||||
};
|
||||
|
||||
let included_in_extrinsic =
|
||||
try_or_throw_null!(jni_env, jni_env.convert_byte_array(signed_extras));
|
||||
let included_in_signed_data =
|
||||
try_or_throw_null!(jni_env, jni_env.convert_byte_array(additional_signed));
|
||||
|
||||
let call_vec = try_or_throw_null!(jni_env, jni_env.convert_byte_array(call));
|
||||
|
||||
let signed_ext_data = SignedExtrinsicData {
|
||||
included_in_extrinsic: included_in_extrinsic.as_slice(),
|
||||
included_in_signed_data: included_in_signed_data.as_slice(),
|
||||
};
|
||||
|
||||
let spec_version = spec_version as u32;
|
||||
let spec_name = try_or_throw_null!(jni_env, jni_env.get_string(spec_name));
|
||||
let base58_prefix = base58_prefix as u16;
|
||||
let decimals = decimals as u8;
|
||||
let token_symbol = try_or_throw_null!(jni_env, jni_env.get_string(token_symbol));
|
||||
|
||||
let extra_info = ExtraInfo {
|
||||
spec_version: spec_version,
|
||||
spec_name: spec_name.into(),
|
||||
base58_prefix: base58_prefix,
|
||||
decimals: decimals,
|
||||
token_symbol: token_symbol.into(),
|
||||
};
|
||||
|
||||
let extrinsic_metadata = FrameMetadataPrepared::prepare(&metadata)
|
||||
.unwrap()
|
||||
.as_type_information()
|
||||
.unwrap()
|
||||
.extrinsic_metadata;
|
||||
|
||||
let Ok(registry_proof) =
|
||||
generate_proof_for_extrinsic_parts(call_vec.as_slice(), Some(signed_ext_data), &metadata)
|
||||
else {
|
||||
jni_env
|
||||
.throw_new("java/lang/Exception", "Failed to construct proof")
|
||||
.unwrap();
|
||||
return ptr::null_mut();
|
||||
};
|
||||
|
||||
let meta_proof = MetadataProof {
|
||||
proof: registry_proof,
|
||||
extrinsic: extrinsic_metadata,
|
||||
extra_info: extra_info,
|
||||
};
|
||||
|
||||
let prood_encoded = meta_proof.encode();
|
||||
|
||||
try_or_throw_null!(
|
||||
jni_env,
|
||||
jni_env.byte_array_from_slice(prood_encoded.as_slice().as_ref())
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn Java_io_novafoundation_nova_metadata_1shortener_MetadataShortener_generate_1metadata_1digest(
|
||||
jni_env: JNIEnv,
|
||||
_: JClass,
|
||||
metadata: jbyteArray,
|
||||
spec_version: jint,
|
||||
spec_name: JString,
|
||||
base58_prefix: jint,
|
||||
decimals: jint,
|
||||
token_symbol: JString,
|
||||
) -> jbyteArray {
|
||||
let Some(metadata) = decode_metadata(&jni_env, metadata) else {
|
||||
return ptr::null_mut();
|
||||
};
|
||||
|
||||
let spec_version = spec_version as u32;
|
||||
let spec_name = try_or_throw_null!(jni_env, jni_env.get_string(spec_name));
|
||||
let base58_prefix = base58_prefix as u16;
|
||||
let decimals = decimals as u8;
|
||||
let token_symbol = try_or_throw_null!(jni_env, jni_env.get_string(token_symbol));
|
||||
|
||||
let extra_info = ExtraInfo {
|
||||
spec_version: spec_version,
|
||||
spec_name: spec_name.into(),
|
||||
base58_prefix: base58_prefix,
|
||||
decimals: decimals,
|
||||
token_symbol: token_symbol.into(),
|
||||
};
|
||||
|
||||
let Ok(digest) = generate_metadata_digest(&metadata, extra_info) else {
|
||||
jni_env
|
||||
.throw_new("java/lang/Exception", "Failed to generate digest")
|
||||
.unwrap();
|
||||
return ptr::null_mut();
|
||||
};
|
||||
|
||||
let digest_hash = digest.hash();
|
||||
|
||||
try_or_throw_null!(
|
||||
jni_env,
|
||||
jni_env.byte_array_from_slice(digest_hash.as_slice().as_ref())
|
||||
)
|
||||
}
|
||||
|
||||
fn decode_metadata(jni_env: &JNIEnv, metadata: jbyteArray) -> Option<RuntimeMetadata> {
|
||||
let metadata = try_or_throw!(jni_env, jni_env.convert_byte_array(metadata), None);
|
||||
|
||||
let Some(metadata) = Option::<OpaqueMetadata>::decode(&mut &metadata[..])
|
||||
.ok()
|
||||
.flatten() else {
|
||||
jni_env
|
||||
.throw_new("java/lang/Exception", "Failed to decode opaque metadata")
|
||||
.unwrap();
|
||||
|
||||
return None;
|
||||
};
|
||||
let metadata = metadata.0;
|
||||
|
||||
let Ok(metadata) = RuntimeMetadataPrefixed::decode(&mut &metadata[..]) else {
|
||||
jni_env
|
||||
.throw_new("java/lang/Exception", "Failed to decode metadata")
|
||||
.unwrap();
|
||||
|
||||
return None
|
||||
};
|
||||
|
||||
Some(metadata.1)
|
||||
}
|
||||
|
||||
// fn main() {
|
||||
// let signed_extras = "15000000";
|
||||
// let additional_signed = "104a0f001900000091b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c36c9f8deedd0c7f1aae4d1900c88456f23d9c224934e6b8c57f750c8b146997c1";
|
||||
// let call = "050000010101010101010101010101010101010101010101010101010101010101010104";
|
||||
// let metadata = "Metadata goes here";
|
||||
|
||||
// let signed_extras = hex2bytes(signed_extras).expect("Cant decode signed extras");
|
||||
// let additional_signed = hex2bytes(additional_signed).expect("Cant decode additional signed");
|
||||
// let call = hex2bytes(call).expect("Cant decode call");
|
||||
|
||||
|
||||
// let metadata = hex2bytes(metadata).expect("Cant decode metadata");
|
||||
// let metadata = Option::<OpaqueMetadata>::decode(&mut &metadata[..])
|
||||
// .expect("Failed to decode opaque metadata")
|
||||
// .expect("Metadata V15 support is required.")
|
||||
// .0;
|
||||
// let metadata = RuntimeMetadataPrefixed::decode(&mut &metadata[..]).expect("Failed to decode metadata");
|
||||
|
||||
|
||||
// let signed_ext_data = SignedExtrinsicData {
|
||||
// included_in_extrinsic: signed_extras.as_slice(),
|
||||
// included_in_signed_data: additional_signed.as_slice(),
|
||||
// };
|
||||
|
||||
// let proof = generate_proof_for_extrinsic_parts(call.as_slice(), Some(signed_ext_data), &metadata.1)
|
||||
// .expect("Failed to generate proof");
|
||||
// }
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
</manifest>
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package io.novafoundation.nova.metadata_shortener;
|
||||
|
||||
public class MetadataShortener {
|
||||
|
||||
static {
|
||||
System.loadLibrary("metadata_shortener_java");
|
||||
}
|
||||
|
||||
public static native byte[] generate_extrinsic_proof(
|
||||
byte[] call,
|
||||
byte[] signed_extras,
|
||||
byte[] additional_signed,
|
||||
byte[] metadata,
|
||||
|
||||
int spec_version,
|
||||
String spec_name,
|
||||
int base58_prefix,
|
||||
int decimals,
|
||||
String token_symbol
|
||||
);
|
||||
|
||||
public static native byte[] generate_metadata_digest(
|
||||
byte[] metadata,
|
||||
int spec_version,
|
||||
String spec_name,
|
||||
int base58_prefix,
|
||||
int decimals,
|
||||
String token_symbol
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
/build
|
||||
/rust/target/
|
||||
@@ -0,0 +1,37 @@
|
||||
apply plugin: 'org.mozilla.rust-android-gradle.rust-android'
|
||||
|
||||
android {
|
||||
namespace 'io.novafoundation.nova.sr25519_bizinikiwi'
|
||||
|
||||
ndkVersion "26.1.10909125"
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation kotlinDep
|
||||
|
||||
testImplementation jUnitDep
|
||||
|
||||
androidTestImplementation androidTestRunnerDep
|
||||
androidTestImplementation androidTestRulesDep
|
||||
androidTestImplementation androidJunitDep
|
||||
}
|
||||
|
||||
cargo {
|
||||
module = "rust/"
|
||||
libname = "sr25519_bizinikiwi_java"
|
||||
targets = ["arm", "arm64", "x86", "x86_64"]
|
||||
profile = "release"
|
||||
pythonCommand = "python3"
|
||||
}
|
||||
|
||||
tasks.matching { it.name.matches(/merge.*JniLibFolders/) }.configureEach {
|
||||
it.inputs.dir(new File(buildDir, "rustJniLibs/android"))
|
||||
it.dependsOn("cargoBuild")
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
# Keep BizinikiwSr25519 native methods
|
||||
-keep class io.novafoundation.nova.sr25519.BizinikiwSr25519 { *; }
|
||||
@@ -0,0 +1,7 @@
|
||||
# Keep native methods
|
||||
-keepclasseswithmembernames class * {
|
||||
native <methods>;
|
||||
}
|
||||
|
||||
# Keep BizinikiwSr25519 object
|
||||
-keep class io.novafoundation.nova.sr25519.BizinikiwSr25519 { *; }
|
||||
+583
@@ -0,0 +1,583 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aead"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0"
|
||||
dependencies = [
|
||||
"crypto-common",
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arrayref"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb"
|
||||
|
||||
[[package]]
|
||||
name = "arrayvec"
|
||||
version = "0.7.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.10.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "cesu8"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "combine"
|
||||
version = "4.6.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba5a308b75df32fe02788e748662718f03fde005016435c444eea572398219fd"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-common"
|
||||
version = "0.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"rand_core",
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek"
|
||||
version = "4.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"curve25519-dalek-derive",
|
||||
"digest",
|
||||
"fiat-crypto",
|
||||
"rustc_version",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "curve25519-dalek-derive"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||
dependencies = [
|
||||
"block-buffer",
|
||||
"crypto-common",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fiat-crypto"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom_or_panic"
|
||||
version = "0.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea1015b5a70616b688dc230cfe50c8af89d972cb132d5a622814d29773b10b9"
|
||||
dependencies = [
|
||||
"rand",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni"
|
||||
version = "0.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97"
|
||||
dependencies = [
|
||||
"cesu8",
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"jni-sys",
|
||||
"log",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jni-sys"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
|
||||
|
||||
[[package]]
|
||||
name = "keccak"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654"
|
||||
dependencies = [
|
||||
"cpufeatures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.180"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "merlin"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58c38e2799fc0978b65dfff8023ec7843e2330bb462f19198840b34b6582397d"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"keccak",
|
||||
"rand_core",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
|
||||
dependencies = [
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schnorrkel"
|
||||
version = "0.11.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e9fcb6c2e176e86ec703e22560d99d65a5ee9056ae45a08e13e84ebf796296f"
|
||||
dependencies = [
|
||||
"aead",
|
||||
"arrayref",
|
||||
"arrayvec",
|
||||
"curve25519-dalek",
|
||||
"getrandom_or_panic",
|
||||
"merlin",
|
||||
"rand_core",
|
||||
"serde_bytes",
|
||||
"sha2",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_bytes"
|
||||
version = "0.11.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a5d440709e79d88e51ac01c4b72fc6cb7314017bb7da9eeff678aa94c10e3ea8"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_core"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.228"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.10.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"cpufeatures",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sr25519-bizinikiwi-java"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"jni",
|
||||
"schnorrkel",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.114"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db6d35d663eadb6c932438e763b262fe1a70987f9ae936e60158176d710cae4a"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.39"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4122cd3169e94605190e77839c9a40d40ed048d305bfdc146e7df40ab0f3e517"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
|
||||
dependencies = [
|
||||
"zeroize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize_derive"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
@@ -0,0 +1,20 @@
|
||||
[package]
|
||||
authors = ['PezkuwiChain']
|
||||
edition = '2021'
|
||||
license = 'Apache 2.0'
|
||||
name = "sr25519-bizinikiwi-java"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
schnorrkel = "0.11.4"
|
||||
jni = { version = "0.21", default-features = false }
|
||||
zeroize = "1.7"
|
||||
|
||||
[profile.release]
|
||||
strip = true
|
||||
lto = true
|
||||
opt-level = "s"
|
||||
|
||||
[lib]
|
||||
name = "sr25519_bizinikiwi_java"
|
||||
crate_type = ["cdylib"]
|
||||
@@ -0,0 +1,131 @@
|
||||
use jni::JNIEnv;
|
||||
use jni::objects::{JByteArray, JClass};
|
||||
use jni::sys::jbyteArray;
|
||||
use schnorrkel::{ExpansionMode, Keypair, MiniSecretKey, PublicKey, SecretKey, Signature};
|
||||
use schnorrkel::context::signing_context;
|
||||
|
||||
/// Pezkuwi signing context - different from standard "substrate"
|
||||
const BIZINIKIWI_CTX: &[u8] = b"bizinikiwi";
|
||||
|
||||
const KEYPAIR_LENGTH: usize = 96;
|
||||
const SECRET_KEY_LENGTH: usize = 64;
|
||||
const PUBLIC_KEY_LENGTH: usize = 32;
|
||||
const SIGNATURE_LENGTH: usize = 64;
|
||||
const SEED_LENGTH: usize = 32;
|
||||
|
||||
fn create_from_seed(seed: &[u8]) -> Keypair {
|
||||
match MiniSecretKey::from_bytes(seed) {
|
||||
Ok(mini) => mini.expand_to_keypair(ExpansionMode::Ed25519),
|
||||
Err(_) => panic!("Invalid seed provided"),
|
||||
}
|
||||
}
|
||||
|
||||
fn create_from_pair(pair: &[u8]) -> Keypair {
|
||||
match Keypair::from_bytes(pair) {
|
||||
Ok(kp) => kp,
|
||||
Err(_) => panic!("Invalid keypair provided"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sign a message using bizinikiwi context
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_io_novafoundation_nova_sr25519_BizinikiwSr25519_sign<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
public_key: JByteArray<'local>,
|
||||
secret_key: JByteArray<'local>,
|
||||
message: JByteArray<'local>,
|
||||
) -> jbyteArray {
|
||||
let public_vec = env.convert_byte_array(&public_key).expect("Invalid public key");
|
||||
let secret_vec = env.convert_byte_array(&secret_key).expect("Invalid secret key");
|
||||
let message_vec = env.convert_byte_array(&message).expect("Invalid message");
|
||||
|
||||
let secret = SecretKey::from_bytes(&secret_vec).expect("Invalid secret key bytes");
|
||||
let public = PublicKey::from_bytes(&public_vec).expect("Invalid public key bytes");
|
||||
|
||||
let context = signing_context(BIZINIKIWI_CTX);
|
||||
let signature = secret.sign(context.bytes(&message_vec), &public);
|
||||
|
||||
let output = env.byte_array_from_slice(signature.to_bytes().as_ref())
|
||||
.expect("Failed to create signature array");
|
||||
|
||||
output.into_raw()
|
||||
}
|
||||
|
||||
/// Verify a signature using bizinikiwi context
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_io_novafoundation_nova_sr25519_BizinikiwSr25519_verify<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
signature: JByteArray<'local>,
|
||||
message: JByteArray<'local>,
|
||||
public_key: JByteArray<'local>,
|
||||
) -> bool {
|
||||
let sig_vec = env.convert_byte_array(&signature).expect("Invalid signature");
|
||||
let msg_vec = env.convert_byte_array(&message).expect("Invalid message");
|
||||
let pub_vec = env.convert_byte_array(&public_key).expect("Invalid public key");
|
||||
|
||||
let sig = match Signature::from_bytes(&sig_vec) {
|
||||
Ok(s) => s,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
let public = match PublicKey::from_bytes(&pub_vec) {
|
||||
Ok(p) => p,
|
||||
Err(_) => return false,
|
||||
};
|
||||
|
||||
let context = signing_context(BIZINIKIWI_CTX);
|
||||
public.verify(context.bytes(&msg_vec), &sig).is_ok()
|
||||
}
|
||||
|
||||
/// Generate keypair from seed
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_io_novafoundation_nova_sr25519_BizinikiwSr25519_keypairFromSeed<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
seed: JByteArray<'local>,
|
||||
) -> jbyteArray {
|
||||
let seed_vec = env.convert_byte_array(&seed).expect("Invalid seed");
|
||||
|
||||
let keypair = create_from_seed(&seed_vec);
|
||||
|
||||
let output = env.byte_array_from_slice(&keypair.to_bytes())
|
||||
.expect("Failed to create keypair array");
|
||||
|
||||
output.into_raw()
|
||||
}
|
||||
|
||||
/// Get public key from keypair
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_io_novafoundation_nova_sr25519_BizinikiwSr25519_publicKeyFromKeypair<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
keypair: JByteArray<'local>,
|
||||
) -> jbyteArray {
|
||||
let keypair_vec = env.convert_byte_array(&keypair).expect("Invalid keypair");
|
||||
|
||||
let kp = create_from_pair(&keypair_vec);
|
||||
|
||||
let output = env.byte_array_from_slice(kp.public.to_bytes().as_ref())
|
||||
.expect("Failed to create public key array");
|
||||
|
||||
output.into_raw()
|
||||
}
|
||||
|
||||
/// Get secret key from keypair (64 bytes: 32 key + 32 nonce)
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_io_novafoundation_nova_sr25519_BizinikiwSr25519_secretKeyFromKeypair<'local>(
|
||||
mut env: JNIEnv<'local>,
|
||||
_class: JClass<'local>,
|
||||
keypair: JByteArray<'local>,
|
||||
) -> jbyteArray {
|
||||
let keypair_vec = env.convert_byte_array(&keypair).expect("Invalid keypair");
|
||||
|
||||
let kp = create_from_pair(&keypair_vec);
|
||||
|
||||
let output = env.byte_array_from_slice(&kp.secret.to_bytes())
|
||||
.expect("Failed to create secret key array");
|
||||
|
||||
output.into_raw()
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<manifest />
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
package io.novafoundation.nova.sr25519
|
||||
|
||||
/**
|
||||
* SR25519 signing implementation for PezkuwiChain using "bizinikiwi" signing context.
|
||||
*
|
||||
* Standard Substrate chains use "substrate" context, but Pezkuwi ecosystem uses "bizinikiwi".
|
||||
* This native library provides signing compatible with @pezkuwi/scure-sr25519.
|
||||
*/
|
||||
object BizinikiwSr25519 {
|
||||
|
||||
init {
|
||||
System.loadLibrary("sr25519_bizinikiwi_java")
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign a message using SR25519 with bizinikiwi context.
|
||||
*
|
||||
* @param publicKey 32-byte public key
|
||||
* @param secretKey 64-byte secret key (32-byte scalar + 32-byte nonce)
|
||||
* @param message Message bytes to sign
|
||||
* @return 64-byte signature
|
||||
*/
|
||||
external fun sign(publicKey: ByteArray, secretKey: ByteArray, message: ByteArray): ByteArray
|
||||
|
||||
/**
|
||||
* Verify a signature using bizinikiwi context.
|
||||
*
|
||||
* @param signature 64-byte signature
|
||||
* @param message Original message bytes
|
||||
* @param publicKey 32-byte public key
|
||||
* @return true if signature is valid
|
||||
*/
|
||||
external fun verify(signature: ByteArray, message: ByteArray, publicKey: ByteArray): Boolean
|
||||
|
||||
/**
|
||||
* Generate a keypair from a 32-byte seed.
|
||||
*
|
||||
* @param seed 32-byte seed (mini secret key)
|
||||
* @return 96-byte keypair (32 key + 32 nonce + 32 public)
|
||||
*/
|
||||
external fun keypairFromSeed(seed: ByteArray): ByteArray
|
||||
|
||||
/**
|
||||
* Extract public key from keypair.
|
||||
*
|
||||
* @param keypair 96-byte keypair
|
||||
* @return 32-byte public key
|
||||
*/
|
||||
external fun publicKeyFromKeypair(keypair: ByteArray): ByteArray
|
||||
|
||||
/**
|
||||
* Extract secret key from keypair.
|
||||
*
|
||||
* @param keypair 96-byte keypair
|
||||
* @return 64-byte secret key
|
||||
*/
|
||||
external fun secretKeyFromKeypair(keypair: ByteArray): ByteArray
|
||||
}
|
||||
Reference in New Issue
Block a user