ref(dubp):make really async & rework handle error in a more generic way

This commit is contained in:
librelois 2021-01-09 21:12:52 +01:00
parent 2763da7174
commit b288b601ce
10 changed files with 333 additions and 177 deletions

3
.cargo/config.toml Normal file
View File

@ -0,0 +1,3 @@
[alias]
bd = "make android-dev32"
br = "make"

71
Cargo.lock generated
View File

@ -59,6 +59,15 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
[[package]]
name = "async-oneshot"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "50f4770cbbff928c30a991de67fb3976f44d8e3e202f8c79ef91b47006e04904"
dependencies = [
"futures-micro",
]
[[package]] [[package]]
name = "atty" name = "atty"
version = "0.2.14" version = "0.2.14"
@ -245,6 +254,8 @@ dependencies = [
"cbindgen", "cbindgen",
"dart-bindgen", "dart-bindgen",
"dup-crypto", "dup-crypto",
"fast-threadpool",
"once_cell",
"thiserror", "thiserror",
] ]
@ -270,6 +281,32 @@ dependencies = [
"zeroize", "zeroize",
] ]
[[package]]
name = "fast-threadpool"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccb66774e02743b4be61c19e09bf59de9058e9a7b4096040689003e7a901a3d"
dependencies = [
"async-oneshot",
"flume",
"num_cpus",
]
[[package]]
name = "flume"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0362ef9c4c1fa854ff95b4cb78045a86e810d804dc04937961988b45427104a9"
dependencies = [
"spinning_top",
]
[[package]]
name = "futures-micro"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61e9325be55c5581082cd110294fa988c1f920bc573ec370ef201e33c469a95a"
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.4" version = "0.14.4"
@ -344,6 +381,15 @@ version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb" checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "lock_api"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
dependencies = [
"scopeguard",
]
[[package]] [[package]]
name = "log" name = "log"
version = "0.4.11" version = "0.4.11"
@ -353,6 +399,16 @@ dependencies = [
"cfg-if 0.1.10", "cfg-if 0.1.10",
] ]
[[package]]
name = "num_cpus"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
dependencies = [
"hermit-abi",
"libc",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.5.2" version = "1.5.2"
@ -466,6 +522,12 @@ version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.118" version = "1.0.118"
@ -503,6 +565,15 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spinning_top"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7e529d73e80d64b5f2631f9035113347c578a1c9c7774b83a2b880788459ab36"
dependencies = [
"lock_api",
]
[[package]] [[package]]
name = "strsim" name = "strsim"
version = "0.8.0" version = "0.8.0"

View File

@ -11,6 +11,8 @@ crate-type = ["rlib"]
[dependencies] [dependencies]
allo-isolate = "0.1.6" allo-isolate = "0.1.6"
dup-crypto = { version = "0.36.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] } dup-crypto = { version = "0.36.0", features = ["dewif", "mnemonic", "mnemonic_french", "rand", "scrypt"] }
fast-threadpool = { version = "0.3.0", default-features = false }
once_cell = { version = "1.3.1", default-features = false, features = ["std"] }
thiserror = "1.0.23" thiserror = "1.0.23"
[build-dependencies] [build-dependencies]

View File

@ -0,0 +1,42 @@
// Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::*;
static THREAD_POOL: Lazy<ThreadPoolSyncHandler<()>> = Lazy::new(|| {
ThreadPool::start(ThreadPoolConfig::low().queue_size(Some(16)), ()).into_sync_handler()
});
pub(crate) fn exec_async<F, F2, P, R>(port: i64, parse_params: F, async_job: F2)
where
P: 'static + Send + Sync,
F: FnOnce() -> Result<P, DubpError>,
F2: 'static + Send + Sync + FnOnce(P) -> R,
DartRes: From<R>,
{
match parse_params() {
Ok(parsed_params) => {
if THREAD_POOL
.launch(move |_| Isolate::new(port).post(DartRes::from(async_job(parsed_params))))
.is_err()
{
Isolate::new(port).post(DartRes::err("thread pool panicked"));
}
}
Err(e) => {
Isolate::new(port).post(DartRes::err(e));
}
}
}

View File

@ -35,16 +35,11 @@ pub(super) fn gen_pin10() -> Result<String, DubpError> {
} }
pub(super) fn change_pin( pub(super) fn change_pin(
currency: *const raw::c_char, currency: &str,
dewif: *const raw::c_char, dewif: &str,
old_pin: *const raw::c_char, old_pin: &str,
new_pin: *const raw::c_char, new_pin: &str,
) -> Result<String, DubpError> { ) -> Result<String, DubpError> {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let old_pin = char_ptr_to_str(old_pin)?;
let new_pin = char_ptr_to_str(new_pin)?;
let currency = parse_currency(currency)?; let currency = parse_currency(currency)?;
let mut keypairs = dup_crypto::dewif::read_dewif_file_content( let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
ExpectedCurrency::Specific(currency), ExpectedCurrency::Specific(currency),
@ -62,15 +57,11 @@ pub(super) fn change_pin(
} }
pub(super) fn gen_dewif( pub(super) fn gen_dewif(
currency: *const raw::c_char, currency: &str,
language: u32, language: u32,
mnemonic: *const raw::c_char, mnemonic: &str,
pin: *const raw::c_char, pin: &str,
) -> Result<String, DubpError> { ) -> Result<String, DubpError> {
let currency = char_ptr_to_str(currency)?;
let mnemonic = char_ptr_to_str(mnemonic)?;
let pin = char_ptr_to_str(pin)?;
let currency = parse_currency(currency)?; let currency = parse_currency(currency)?;
let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?) let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?)
.map_err(|_| DubpError::WrongLanguage)?; .map_err(|_| DubpError::WrongLanguage)?;
@ -81,15 +72,7 @@ pub(super) fn gen_dewif(
)) ))
} }
pub(super) fn get_pubkey( pub(super) fn get_pubkey(currency: &str, dewif: &str, pin: &str) -> Result<String, DubpError> {
currency: *const raw::c_char,
dewif: *const raw::c_char,
pin: *const raw::c_char,
) -> Result<String, DubpError> {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let pin = char_ptr_to_str(pin)?;
let currency = parse_currency(currency)?; let currency = parse_currency(currency)?;
let mut keypairs = dup_crypto::dewif::read_dewif_file_content( let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
ExpectedCurrency::Specific(currency), ExpectedCurrency::Specific(currency),
@ -104,17 +87,7 @@ pub(super) fn get_pubkey(
} }
} }
pub(super) fn sign( pub(super) fn sign(currency: &str, dewif: &str, pin: &str, msg: &str) -> Result<String, DubpError> {
currency: *const raw::c_char,
dewif: *const raw::c_char,
pin: *const raw::c_char,
msg: *const raw::c_char,
) -> Result<String, DubpError> {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let pin = char_ptr_to_str(pin)?;
let msg = char_ptr_to_str(msg)?;
let currency = parse_currency(currency)?; let currency = parse_currency(currency)?;
let mut keypairs = dup_crypto::dewif::read_dewif_file_content( let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
ExpectedCurrency::Specific(currency), ExpectedCurrency::Specific(currency),
@ -130,22 +103,11 @@ pub(super) fn sign(
} }
pub(super) fn sign_several( pub(super) fn sign_several(
currency: *const raw::c_char, currency: &str,
dewif: *const raw::c_char, dewif: &str,
pin: *const raw::c_char, pin: &str,
msgs_len: usize, msgs: &[&str],
msgs: *const *const raw::c_char,
) -> Result<Vec<String>, DubpError> { ) -> Result<Vec<String>, DubpError> {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let pin = char_ptr_to_str(pin)?;
let msgs_slice: &[*const raw::c_char] = unsafe { std::slice::from_raw_parts(msgs, msgs_len) };
let mut msgs = Vec::with_capacity(msgs_len);
for ptr_c_char in msgs_slice {
msgs.push(char_ptr_to_str(*ptr_c_char)?);
}
let currency = parse_currency(currency)?; let currency = parse_currency(currency)?;
let mut keypairs = dup_crypto::dewif::read_dewif_file_content( let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
ExpectedCurrency::Specific(currency), ExpectedCurrency::Specific(currency),

View File

@ -0,0 +1,77 @@
// Copyright (C) 2020 Éloïs SANCHEZ.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
use crate::*;
/// Dubp error
#[derive(Debug, Error)]
pub(crate) enum DubpError {
#[error("{0}")]
DewifReadError(DewifReadError),
#[error("I/O error: {0}")]
IoErr(io::Error),
#[error("A given parameter is null")]
NullParamErr,
#[error("fail to generate random bytes")]
RandErr,
#[error("Unknown currency name")]
UnknownCurrencyName,
#[error("Unknown language")]
UnknownLanguage,
#[error("{0}")]
Utf8Error(std::str::Utf8Error),
#[error("Wrong language")]
WrongLanguage,
}
impl From<io::Error> for DubpError {
fn from(e: io::Error) -> Self {
Self::IoErr(e)
}
}
pub(crate) struct DartRes(allo_isolate::ffi::DartCObject);
impl DartRes {
pub(crate) fn err<E: ToString>(e: E) -> allo_isolate::ffi::DartCObject {
vec![format!("DUBP_RS_ERROR: {}", e.to_string())].into_dart()
}
}
impl IntoDart for DartRes {
fn into_dart(self) -> allo_isolate::ffi::DartCObject {
self.0.into_dart()
}
}
impl<E> From<Result<String, E>> for DartRes
where
E: ToString,
{
fn from(res: Result<String, E>) -> Self {
match res {
Ok(string) => Self(string.into_dart()),
Err(e) => Self(format!("DUBP_RS_ERROR: {}", e.to_string()).into_dart()),
}
}
}
impl<E> From<Result<Vec<String>, E>> for DartRes
where
E: ToString,
{
fn from(res: Result<Vec<String>, E>) -> Self {
match res {
Ok(vec_string) => Self(vec_string.into_dart()),
Err(e) => Self(vec![format!("DUBP_RS_ERROR: {}", e.to_string())].into_dart()),
}
}
}

View File

@ -15,9 +15,13 @@
#![allow(clippy::missing_safety_doc, clippy::not_unsafe_ptr_arg_deref)] #![allow(clippy::missing_safety_doc, clippy::not_unsafe_ptr_arg_deref)]
mod r#async;
mod dewif; mod dewif;
mod error;
mod mnemonic; mod mnemonic;
use crate::error::{DartRes, DubpError};
use crate::r#async::exec_async;
use allo_isolate::{IntoDart, Isolate}; use allo_isolate::{IntoDart, Isolate};
use dup_crypto::{ use dup_crypto::{
bases::b58::ToBase58, bases::b58::ToBase58,
@ -28,65 +32,11 @@ use dup_crypto::{
}, },
mnemonic::{Language, Mnemonic, MnemonicType}, mnemonic::{Language, Mnemonic, MnemonicType},
}; };
use fast_threadpool::{ThreadPool, ThreadPoolConfig, ThreadPoolSyncHandler};
use once_cell::sync::Lazy;
use std::{ffi::CStr, io, os::raw}; use std::{ffi::CStr, io, os::raw};
use thiserror::Error; use thiserror::Error;
/// Dubp error
#[derive(Debug, Error)]
pub enum DubpError {
#[error("{0}")]
DewifReadError(DewifReadError),
#[error("I/O error: {0}")]
IoErr(io::Error),
#[error("A given parameter is null")]
NullParamErr,
#[error("fail to generate random bytes")]
RandErr,
#[error("Unknown currency name")]
UnknownCurrencyName,
#[error("Unknown language")]
UnknownLanguage,
#[error("{0}")]
Utf8Error(std::str::Utf8Error),
#[error("Wrong language")]
WrongLanguage,
}
impl From<io::Error> for DubpError {
fn from(e: io::Error) -> Self {
Self::IoErr(e)
}
}
struct DartRes(allo_isolate::ffi::DartCObject);
impl IntoDart for DartRes {
fn into_dart(self) -> allo_isolate::ffi::DartCObject {
self.0.into_dart()
}
}
impl<E> From<Result<String, E>> for DartRes
where
E: ToString,
{
fn from(res: Result<String, E>) -> Self {
match res {
Ok(string) => Self(vec![string].into_dart()),
Err(e) => Self(vec![String::from("_"), e.to_string()].into_dart()),
}
}
}
impl<E> From<Result<Vec<String>, E>> for DartRes
where
E: ToString,
{
fn from(res: Result<Vec<String>, E>) -> Self {
match res {
Ok(vec_string) => Self(vec_string.into_dart()),
Err(e) => Self(vec![String::with_capacity(0), e.to_string()].into_dart()),
}
}
}
pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a str, DubpError> { pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a str, DubpError> {
if c_char_ptr.is_null() { if c_char_ptr.is_null() {
Err(DubpError::NullParamErr) Err(DubpError::NullParamErr)
@ -95,6 +45,28 @@ pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a
} }
} }
fn char_ptr_prt_to_vec_str<'a>(
char_ptr_ptr: *const *const raw::c_char,
len: u32,
) -> Result<Vec<&'a str>, DubpError> {
let len = len as usize;
let char_ptr_slice: &[*const raw::c_char] =
unsafe { std::slice::from_raw_parts(char_ptr_ptr, len) };
let mut str_vec = Vec::with_capacity(len);
for char_ptr in char_ptr_slice {
str_vec.push(char_ptr_to_str(*char_ptr)?);
}
Ok(str_vec)
}
fn u32_to_language(i: u32) -> Result<Language, DubpError> {
match i {
0 => Ok(Language::English),
1 => Ok(Language::French),
_ => Err(DubpError::UnknownLanguage),
}
}
#[no_mangle] #[no_mangle]
pub extern "C" fn change_dewif_pin( pub extern "C" fn change_dewif_pin(
port: i64, port: i64,
@ -103,9 +75,17 @@ pub extern "C" fn change_dewif_pin(
old_pin: *const raw::c_char, old_pin: *const raw::c_char,
new_pin: *const raw::c_char, new_pin: *const raw::c_char,
) { ) {
Isolate::new(port).post(DartRes::from(dewif::change_pin( exec_async(
currency, dewif, old_pin, new_pin, port,
))); || {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let old_pin = char_ptr_to_str(old_pin)?;
let new_pin = char_ptr_to_str(new_pin)?;
Ok((currency, dewif, old_pin, new_pin))
},
|(currency, dewif, old_pin, new_pin)| dewif::change_pin(currency, dewif, old_pin, new_pin),
)
} }
#[no_mangle] #[no_mangle]
@ -116,9 +96,16 @@ pub extern "C" fn gen_dewif(
mnemonic: *const raw::c_char, mnemonic: *const raw::c_char,
pin: *const raw::c_char, pin: *const raw::c_char,
) { ) {
Isolate::new(port).post(DartRes::from(dewif::gen_dewif( exec_async(
currency, language, mnemonic, pin, port,
))); || {
let currency = char_ptr_to_str(currency)?;
let mnemonic = char_ptr_to_str(mnemonic)?;
let pin = char_ptr_to_str(pin)?;
Ok((currency, language, mnemonic, pin))
},
|(currency, language, mnemonic, pin)| dewif::gen_dewif(currency, language, mnemonic, pin),
)
} }
#[no_mangle] #[no_mangle]
@ -148,7 +135,16 @@ pub extern "C" fn get_dewif_pubkey(
dewif: *const raw::c_char, dewif: *const raw::c_char,
pin: *const raw::c_char, pin: *const raw::c_char,
) { ) {
Isolate::new(port).post(DartRes::from(dewif::get_pubkey(currency, dewif, pin))); exec_async(
port,
|| {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let pin = char_ptr_to_str(pin)?;
Ok((currency, dewif, pin))
},
|(currency, dewif, pin)| dewif::get_pubkey(currency, dewif, pin),
)
} }
#[no_mangle] #[no_mangle]
@ -157,10 +153,14 @@ pub extern "C" fn mnemonic_to_pubkey(
language: u32, language: u32,
mnemonic_phrase: *const raw::c_char, mnemonic_phrase: *const raw::c_char,
) { ) {
Isolate::new(port).post(DartRes::from(mnemonic::mnemonic_to_pubkey( exec_async(
language, port,
mnemonic_phrase, || {
))); let mnemonic_phrase = char_ptr_to_str(mnemonic_phrase)?;
Ok((language, mnemonic_phrase))
},
|(language, mnemonic_phrase)| mnemonic::mnemonic_to_pubkey(language, mnemonic_phrase),
)
} }
#[no_mangle] #[no_mangle]
@ -171,7 +171,17 @@ pub extern "C" fn sign(
pin: *const raw::c_char, pin: *const raw::c_char,
msg: *const raw::c_char, msg: *const raw::c_char,
) { ) {
Isolate::new(port).post(DartRes::from(dewif::sign(currency, dewif, pin, msg))); exec_async(
port,
|| {
let currency = char_ptr_to_str(currency)?;
let dewif = char_ptr_to_str(dewif)?;
let pin = char_ptr_to_str(pin)?;
let msg = char_ptr_to_str(msg)?;
Ok((currency, dewif, pin, msg))
},
|(currency, dewif, pin, msg)| dewif::sign(currency, dewif, pin, msg),
)
} }
#[no_mangle] #[no_mangle]
@ -180,16 +190,18 @@ pub extern "C" fn sign_several(
currency: *const raw::c_char, currency: *const raw::c_char,
dewif: *const raw::c_char, dewif: *const raw::c_char,
pin: *const raw::c_char, pin: *const raw::c_char,
msgs_len: usize, msgs_len: u32,
msgs: *const *const raw::c_char, msgs: *const *const raw::c_char,
) { ) {
Isolate::new(port).post(dewif::sign_several(currency, dewif, pin, msgs_len, msgs)); exec_async(
} port,
|| {
fn u32_to_language(i: u32) -> Result<Language, DubpError> { let currency = char_ptr_to_str(currency)?;
match i { let dewif = char_ptr_to_str(dewif)?;
0 => Ok(Language::English), let pin = char_ptr_to_str(pin)?;
1 => Ok(Language::French), let msgs = char_ptr_prt_to_vec_str(msgs, msgs_len)?;
_ => Err(DubpError::UnknownLanguage), Ok((currency, dewif, pin, msgs))
} },
|(currency, dewif, pin, msgs)| dewif::sign_several(currency, dewif, pin, &msgs),
)
} }

View File

@ -21,12 +21,7 @@ pub(super) fn gen_mnemonic(language: u32) -> Result<String, DubpError> {
Ok(mnemonic.phrase().to_owned()) Ok(mnemonic.phrase().to_owned())
} }
pub(super) fn mnemonic_to_pubkey( pub(super) fn mnemonic_to_pubkey(language: u32, mnemonic: &str) -> Result<String, DubpError> {
language: u32,
mnemonic: *const raw::c_char,
) -> Result<String, DubpError> {
let mnemonic = char_ptr_to_str(mnemonic)?;
let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?) let mnemonic = Mnemonic::from_phrase(mnemonic, u32_to_language(language)?)
.map_err(|_| DubpError::WrongLanguage)?; .map_err(|_| DubpError::WrongLanguage)?;
let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic); let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic);

View File

@ -55,7 +55,7 @@ class DubpRust {
static Future<String> genMnemonic({Language language = Language.english}) { static Future<String> genMnemonic({Language language = Language.english}) {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.gen_mnemonic( native.gen_mnemonic(
sendPort.nativePort, sendPort.nativePort,
language.index, language.index,
@ -66,7 +66,7 @@ class DubpRust {
static Future<String> _genPin(PinLength pinLength) { static Future<String> _genPin(PinLength pinLength) {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
switch (pinLength) { switch (pinLength) {
case PinLength.ten: case PinLength.ten:
native.gen_pin10( native.gen_pin10(
@ -101,7 +101,7 @@ class DubpRust {
{ {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.change_dewif_pin( native.change_dewif_pin(
sendPort.nativePort, sendPort.nativePort,
Utf8.toUtf8(currency), Utf8.toUtf8(currency),
@ -116,7 +116,7 @@ class DubpRust {
{ {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.get_dewif_pubkey( native.get_dewif_pubkey(
sendPort.nativePort, sendPort.nativePort,
Utf8.toUtf8(currency), Utf8.toUtf8(currency),
@ -148,7 +148,7 @@ class DubpRust {
{ {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.mnemonic_to_pubkey( native.mnemonic_to_pubkey(
sendPort.nativePort, sendPort.nativePort,
language.index, language.index,
@ -161,7 +161,7 @@ class DubpRust {
{ {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.gen_dewif( native.gen_dewif(
sendPort.nativePort, sendPort.nativePort,
Utf8.toUtf8(currency), Utf8.toUtf8(currency),
@ -179,7 +179,7 @@ class DubpRust {
{String currency = "g1", String dewif, String pin}) async { {String currency = "g1", String dewif, String pin}) async {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.get_dewif_pubkey( native.get_dewif_pubkey(
sendPort.nativePort, sendPort.nativePort,
Utf8.toUtf8(currency), Utf8.toUtf8(currency),
@ -196,7 +196,7 @@ class DubpRust {
{String currency = "g1", String dewif, String pin, String message}) { {String currency = "g1", String dewif, String pin, String message}) {
final completer = Completer<String>(); final completer = Completer<String>();
final sendPort = final sendPort =
singleCompletePort<String, List>(completer, callback: _handleErr); singleCompletePort<String, String>(completer, callback: _handleErr);
native.sign( native.sign(
sendPort.nativePort, sendPort.nativePort,
Utf8.toUtf8(currency), Utf8.toUtf8(currency),
@ -243,21 +243,20 @@ class DubpRust {
return ptr; return ptr;
} }
static String _handleErr(List res) { static String _handleErr(String res) {
final List<String> arr = res.cast(); if (res.startsWith('DUBP_RS_ERROR: ')) {
if (arr.length == 1) { final error = res;
return arr[0];
} else {
final error = arr[1];
print(error); print(error);
throw error; throw error;
} else {
return res;
} }
} }
static List<String> _handleErrList(List res) { static List<String> _handleErrList(List res) {
final List<String> arr = res.cast(); final List<String> arr = res.cast();
if (arr.isNotEmpty && arr[0].isEmpty) { if (arr.isNotEmpty && arr[0].startsWith('DUBP_RS_ERROR: ')) {
final error = arr[1]; final error = arr[0];
print(error); print(error);
throw error; throw error;
} else { } else {

View File

@ -21,42 +21,42 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.5.0-nullsafety.3" version: "2.5.0-nullsafety.1"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0-nullsafety.1"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.5" version: "1.1.0-nullsafety.3"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
name: charcode name: charcode
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0-nullsafety.1"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0-nullsafety.1"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.15.0-nullsafety.5" version: "1.15.0-nullsafety.3"
connectivity: connectivity:
dependency: transitive dependency: transitive
description: description:
@ -112,7 +112,7 @@ packages:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0-nullsafety.1"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
@ -282,27 +282,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.3" version: "2.0.3"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.3-nullsafety.3"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.10-nullsafety.3" version: "0.12.10-nullsafety.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0-nullsafety.6" version: "1.3.0-nullsafety.3"
nested: nested:
dependency: transitive dependency: transitive
description: description:
@ -330,7 +323,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.3" version: "1.8.0-nullsafety.1"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
@ -468,42 +461,42 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.0-nullsafety.4" version: "1.8.0-nullsafety.2"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.10.0-nullsafety.6" version: "1.10.0-nullsafety.1"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.3" version: "2.1.0-nullsafety.1"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0-nullsafety.3" version: "1.1.0-nullsafety.1"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0-nullsafety.3" version: "1.2.0-nullsafety.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.19-nullsafety.6" version: "0.2.19-nullsafety.2"
truncate: truncate:
dependency: "direct main" dependency: "direct main"
description: description:
@ -517,7 +510,7 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0-nullsafety.5" version: "1.3.0-nullsafety.3"
uuid: uuid:
dependency: transitive dependency: transitive
description: description:
@ -538,7 +531,7 @@ packages:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0-nullsafety.5" version: "2.1.0-nullsafety.3"
websocket: websocket:
dependency: transitive dependency: transitive
description: description:
@ -575,5 +568,5 @@ packages:
source: hosted source: hosted
version: "2.2.1" version: "2.2.1"
sdks: sdks:
dart: ">=2.12.0-0.0 <3.0.0" dart: ">=2.10.0-110 <2.11.0"
flutter: ">=1.22.0 <2.0.0" flutter: ">=1.22.0 <2.0.0"