forked from axiom-team/gecko
feat(dubp): impl simple payment from transparent account
This commit is contained in:
parent
2d1652db2c
commit
279f35d6c4
File diff suppressed because it is too large
Load Diff
|
@ -11,6 +11,8 @@ crate-type = ["rlib"]
|
|||
|
||||
[dependencies]
|
||||
allo-isolate = "0.1.6"
|
||||
dubp-client = { git = "https://git.duniter.org/libs/dubp-rs-client-lib", branch = "master", features = ["blocking"], default-features = false }
|
||||
#dubp-client= { path = "../dubp-rs-client-lib", features = ["blocking"], default-features = false }
|
||||
dup-crypto = { version = "0.46.0", features = ["bip32-ed25519", "dewif", "mnemonic", "mnemonic_french", "scrypt"] }
|
||||
fast-threadpool = { version = "0.3.0", default-features = false }
|
||||
once_cell = { version = "1.3.1", default-features = false, features = ["std"] }
|
||||
|
|
|
@ -28,9 +28,12 @@ pub(super) fn change_secret_code(
|
|||
let new_log_n = log_n(system_memory);
|
||||
let new_secret_code = gen_secret_code(member_wallet, secret_code_type, new_log_n)?;
|
||||
|
||||
let new_dewif =
|
||||
dup_crypto::dewif::change_dewif_passphrase(dewif, old_secret_code, &new_secret_code)
|
||||
.map_err(DubpError::DewifReadError)?;
|
||||
let new_dewif = dubp_client::crypto::dewif::change_dewif_passphrase(
|
||||
dewif,
|
||||
old_secret_code,
|
||||
&new_secret_code,
|
||||
)
|
||||
.map_err(DubpError::DewifReadError)?;
|
||||
|
||||
Ok(vec![new_dewif, new_secret_code])
|
||||
}
|
||||
|
@ -46,15 +49,20 @@ pub(super) fn gen_dewif(
|
|||
let currency = parse_currency(currency)?;
|
||||
let mnemonic =
|
||||
Mnemonic::from_phrase(mnemonic, language).map_err(|_| DubpError::WrongLanguage)?;
|
||||
let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic);
|
||||
let seed = dubp_client::crypto::mnemonic::mnemonic_to_seed(&mnemonic);
|
||||
|
||||
let log_n = log_n(system_memory);
|
||||
let secret_code = gen_secret_code(member_wallet, secret_code_type, log_n)?;
|
||||
|
||||
let keypair = dup_crypto::keys::ed25519::bip32::KeyPair::from_seed(seed.clone());
|
||||
let keypair = dubp_client::crypto::keys::ed25519::bip32::KeyPair::from_seed(seed.clone());
|
||||
let pubkey = keypair.public_key();
|
||||
let dewif =
|
||||
dup_crypto::dewif::write_dewif_v4_content(currency, log_n, &secret_code, &pubkey, seed);
|
||||
let dewif = dubp_client::crypto::dewif::write_dewif_v4_content(
|
||||
currency,
|
||||
log_n,
|
||||
&secret_code,
|
||||
&pubkey,
|
||||
seed,
|
||||
);
|
||||
|
||||
Ok(vec![dewif, secret_code])
|
||||
}
|
||||
|
@ -64,11 +72,11 @@ pub(super) fn get_dewif_meta(
|
|||
member_wallet: bool,
|
||||
secret_code_type: SecretCodeType,
|
||||
) -> Result<Vec<String>, DubpError> {
|
||||
let dup_crypto::dewif::DewifMeta {
|
||||
let dubp_client::crypto::dewif::DewifMeta {
|
||||
currency,
|
||||
log_n,
|
||||
version,
|
||||
} = dup_crypto::dewif::read_dewif_meta(dewif).map_err(DubpError::DewifReadError)?;
|
||||
} = dubp_client::crypto::dewif::read_dewif_meta(dewif).map_err(DubpError::DewifReadError)?;
|
||||
|
||||
let secret_code_len =
|
||||
crate::secret_code::compute_secret_code_len(member_wallet, secret_code_type, log_n)?;
|
||||
|
@ -98,7 +106,7 @@ pub(super) fn get_pubkey(
|
|||
secret_code,
|
||||
)
|
||||
} else if address_index_opt.is_none() && external_opt.is_none() {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -125,7 +133,7 @@ pub(super) fn get_secret_code_len(
|
|||
let member_wallet = member_wallet != 0;
|
||||
let secret_code_type = SecretCodeType::from(secret_code_type);
|
||||
|
||||
let log_n = dup_crypto::dewif::read_dewif_log_n(ExpectedCurrency::Any, dewif)
|
||||
let log_n = dubp_client::crypto::dewif::read_dewif_log_n(ExpectedCurrency::Any, dewif)
|
||||
.map_err(DubpError::DewifReadError)?;
|
||||
|
||||
Ok(crate::secret_code::compute_secret_code_len(
|
||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) fn get_accounts_pubkeys(
|
|||
if accounts_indexs.contains(&U31::new(0)?) {
|
||||
verify_member_secret_code(currency, dewif, secret_code)?;
|
||||
}
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -53,15 +53,15 @@ pub(crate) fn get_accounts_pubkeys(
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_bip32_pubkey(
|
||||
pub(crate) fn get_bip32_keypair(
|
||||
account_index: u32,
|
||||
address_index_opt: Option<U31>,
|
||||
currency: Currency,
|
||||
dewif: &str,
|
||||
external_opt: Option<bool>,
|
||||
secret_code: &str,
|
||||
) -> Result<String, DubpError> {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
) -> Result<KeyPairEnum, DubpError> {
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -73,12 +73,44 @@ pub(crate) fn get_bip32_pubkey(
|
|||
}
|
||||
|
||||
match keypairs.next() {
|
||||
Some(KeyPairEnum::Bip32Ed25519(master_keypair)) => get_bip32_pubkey_inner(
|
||||
account_index,
|
||||
address_index_opt,
|
||||
external_opt,
|
||||
master_keypair,
|
||||
),
|
||||
Some(KeyPairEnum::Bip32Ed25519(master_keypair)) => {
|
||||
Ok(KeyPairEnum::Bip32Ed25519(master_keypair.derive(
|
||||
z_get_derivation_path(account_index, address_index_opt, external_opt)?,
|
||||
)))
|
||||
}
|
||||
Some(_) => Err(DubpError::NotHdWallet),
|
||||
None => Err(DubpError::DewifReadError(DewifReadError::CorruptedContent)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_bip32_pubkey(
|
||||
account_index: u32,
|
||||
address_index_opt: Option<U31>,
|
||||
currency: Currency,
|
||||
dewif: &str,
|
||||
external_opt: Option<bool>,
|
||||
secret_code: &str,
|
||||
) -> Result<String, DubpError> {
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
)
|
||||
.map_err(DubpError::DewifReadError)?;
|
||||
|
||||
if account_index == 0 {
|
||||
verify_member_secret_code(currency, dewif, secret_code)?;
|
||||
}
|
||||
|
||||
match keypairs.next() {
|
||||
Some(KeyPairEnum::Bip32Ed25519(master_keypair)) => Ok(master_keypair
|
||||
.derive(z_get_derivation_path(
|
||||
account_index,
|
||||
address_index_opt,
|
||||
external_opt,
|
||||
)?)
|
||||
.public_key()
|
||||
.to_base58()),
|
||||
Some(_) => Err(DubpError::NotHdWallet),
|
||||
None => Err(DubpError::DewifReadError(DewifReadError::CorruptedContent)),
|
||||
}
|
||||
|
@ -111,7 +143,7 @@ pub(crate) fn load_opaque_bip32_accounts(
|
|||
dewif: &str,
|
||||
secret_code: &str,
|
||||
) -> Result<(), DubpError> {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -147,7 +179,7 @@ pub(crate) fn sign_bip32(
|
|||
secret_code: &str,
|
||||
msg: &str,
|
||||
) -> Result<String, DubpError> {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -180,7 +212,7 @@ pub(crate) fn sign_several_bip32(
|
|||
secret_code: &str,
|
||||
msgs: &[&str],
|
||||
) -> Result<Vec<String>, DubpError> {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -204,22 +236,6 @@ pub(crate) fn sign_several_bip32(
|
|||
}
|
||||
}
|
||||
|
||||
fn get_bip32_pubkey_inner(
|
||||
account_index: u32,
|
||||
address_index_opt: Option<U31>,
|
||||
external_opt: Option<bool>,
|
||||
master_keypair: KeyPair,
|
||||
) -> Result<String, DubpError> {
|
||||
Ok(master_keypair
|
||||
.derive(z_get_derivation_path(
|
||||
account_index,
|
||||
address_index_opt,
|
||||
external_opt,
|
||||
)?)
|
||||
.public_key()
|
||||
.to_base58())
|
||||
}
|
||||
|
||||
fn sign_bip32_inner(
|
||||
account_index: u32,
|
||||
address_index_opt: Option<U31>,
|
||||
|
@ -265,9 +281,11 @@ fn verify_member_secret_code(
|
|||
secret_code: &str,
|
||||
) -> Result<(), DubpError> {
|
||||
if crate::secret_code::is_ascii_letters(secret_code) {
|
||||
let log_n =
|
||||
dup_crypto::dewif::read_dewif_log_n(ExpectedCurrency::Specific(currency), dewif)
|
||||
.map_err(DubpError::DewifReadError)?;
|
||||
let log_n = dubp_client::crypto::dewif::read_dewif_log_n(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
)
|
||||
.map_err(DubpError::DewifReadError)?;
|
||||
let expected_secret_code_len =
|
||||
crate::secret_code::compute_secret_code_len(true, SecretCodeType::Letters, log_n)?;
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ pub(crate) fn sign(
|
|||
secret_code: &str,
|
||||
msg: &str,
|
||||
) -> Result<String, DubpError> {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
@ -40,7 +40,7 @@ pub(crate) fn sign_several(
|
|||
secret_code: &str,
|
||||
msgs: &[&str],
|
||||
) -> Result<Vec<String>, DubpError> {
|
||||
let mut keypairs = dup_crypto::dewif::read_dewif_file_content(
|
||||
let mut keypairs = dubp_client::crypto::dewif::read_dewif_file_content(
|
||||
ExpectedCurrency::Specific(currency),
|
||||
dewif,
|
||||
&secret_code.to_ascii_uppercase(),
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
use crate::*;
|
||||
|
||||
/// Dubp error
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Debug, Error)]
|
||||
pub(crate) enum DubpError {
|
||||
#[error("{0}")]
|
||||
|
@ -26,6 +27,8 @@ pub(crate) enum DubpError {
|
|||
GetMasterPubkeyOfHdWallet,
|
||||
#[error("Give external bool or address index for legacy wallet.")]
|
||||
GiveExternalBoolOrAddressIndexForLegacyWallet,
|
||||
#[error("{0}")]
|
||||
GvaClientError(dubp_client::GvaClientError),
|
||||
#[error("I/O error: {0}")]
|
||||
IoErr(io::Error),
|
||||
#[error("{0}")]
|
||||
|
@ -33,6 +36,8 @@ pub(crate) enum DubpError {
|
|||
#[error("{0}")]
|
||||
InvalidPubkey(PublicKeyFromStrErr),
|
||||
#[error("{0}")]
|
||||
InvalidScript(dubp_client::documents_parser::TextParseError),
|
||||
#[error("{0}")]
|
||||
InvalidU31(U31Error),
|
||||
#[error("Invalid secret code type")]
|
||||
InvalidSecretCodeType,
|
||||
|
@ -44,6 +49,8 @@ pub(crate) enum DubpError {
|
|||
NullParamErr,
|
||||
#[error("Opaque account not loaded")]
|
||||
OpaqueAccountNotLoaded,
|
||||
#[error("Payment error: {0}")]
|
||||
PaymentError(String),
|
||||
#[error("Secret code too short: please change your secret code")]
|
||||
SecretCodeTooShort,
|
||||
#[error("The chaining address cannot be used to sign with opaque account")]
|
||||
|
|
|
@ -52,6 +52,20 @@ pub(crate) fn char_ptr_to_str<'a>(c_char_ptr: *const raw::c_char) -> Result<&'a
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn char_ptr_to_opt_string(
|
||||
c_char_ptr: *const raw::c_char,
|
||||
) -> Result<Option<String>, DubpError> {
|
||||
Ok(if c_char_ptr.is_null() {
|
||||
None
|
||||
} else {
|
||||
Some(
|
||||
unsafe { CStr::from_ptr(c_char_ptr).to_str() }
|
||||
.map_err(DubpError::Utf8Error)?
|
||||
.to_owned(),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn char_ptr_prt_to_vec_u31(
|
||||
u32_ptr: *const u32,
|
||||
len: u32,
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
use crate::*;
|
||||
use dup_crypto::keys::ed25519::{KeyPairFromSaltedPasswordGenerator, SaltedPassword};
|
||||
use dubp_client::crypto::keys::ed25519::{KeyPairFromSaltedPasswordGenerator, SaltedPassword};
|
||||
|
||||
pub(super) fn gen_dewif_from_legacy(
|
||||
currency: &str,
|
||||
|
@ -30,7 +30,8 @@ pub(super) fn gen_dewif_from_legacy(
|
|||
|
||||
let log_n = crate::dewif::log_n(system_memory);
|
||||
let secret_code = gen_secret_code(member_wallet, secret_code_type, log_n)?;
|
||||
let dewif = dup_crypto::dewif::write_dewif_v3_content(currency, &keypair, log_n, &secret_code);
|
||||
let dewif =
|
||||
dubp_client::crypto::dewif::write_dewif_v3_content(currency, &keypair, log_n, &secret_code);
|
||||
let pubkey = keypair.public_key().to_base58();
|
||||
Ok(vec![dewif, secret_code, pubkey])
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ mod error;
|
|||
mod inputs;
|
||||
mod legacy;
|
||||
mod mnemonic;
|
||||
mod payment;
|
||||
mod pubkey;
|
||||
mod secret_code;
|
||||
|
||||
|
@ -29,7 +30,7 @@ use crate::inputs::*;
|
|||
use crate::r#async::exec_async;
|
||||
use crate::secret_code::gen_secret_code;
|
||||
use allo_isolate::{IntoDart, Isolate};
|
||||
use dup_crypto::{
|
||||
use dubp_client::crypto::{
|
||||
bases::b58::ToBase58,
|
||||
dewif::{Currency, DewifReadError, ExpectedCurrency, G1_CURRENCY, G1_TEST_CURRENCY},
|
||||
keys::{
|
||||
|
@ -459,3 +460,59 @@ pub extern "C" fn sign_several(
|
|||
},
|
||||
)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn simple_payment_bip32(
|
||||
port: i64,
|
||||
account_index: u32,
|
||||
amount: f64,
|
||||
currency: *const raw::c_char,
|
||||
dewif: *const raw::c_char,
|
||||
gva_endpoint: *const raw::c_char,
|
||||
recipient: *const raw::c_char,
|
||||
secret_code: *const raw::c_char,
|
||||
tx_comment: *const raw::c_char,
|
||||
) {
|
||||
exec_async(
|
||||
port,
|
||||
|| {
|
||||
let currency = parse_currency(char_ptr_to_str(currency)?)?;
|
||||
let dewif = char_ptr_to_str(dewif)?;
|
||||
let gva_endpoint = char_ptr_to_str(gva_endpoint)?;
|
||||
let recipient = char_ptr_to_str(recipient)?;
|
||||
let secret_code = char_ptr_to_str(secret_code)?;
|
||||
let tx_comment = char_ptr_to_opt_string(tx_comment)?;
|
||||
Ok((
|
||||
account_index,
|
||||
amount,
|
||||
currency,
|
||||
dewif,
|
||||
gva_endpoint,
|
||||
secret_code,
|
||||
recipient,
|
||||
tx_comment,
|
||||
))
|
||||
},
|
||||
|(
|
||||
account_index,
|
||||
amount,
|
||||
currency,
|
||||
dewif,
|
||||
gva_endpoint,
|
||||
secret_code,
|
||||
recipient,
|
||||
tx_comment,
|
||||
)| {
|
||||
payment::simple_payment(
|
||||
account_index,
|
||||
amount,
|
||||
currency,
|
||||
dewif,
|
||||
gva_endpoint,
|
||||
secret_code,
|
||||
recipient,
|
||||
tx_comment,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ pub(super) fn gen_mnemonic(language: Language) -> Result<String, DubpError> {
|
|||
pub(super) fn mnemonic_to_pubkey(language: Language, mnemonic: &str) -> Result<String, DubpError> {
|
||||
let mnemonic =
|
||||
Mnemonic::from_phrase(mnemonic, language).map_err(|_| DubpError::WrongLanguage)?;
|
||||
let seed = dup_crypto::mnemonic::mnemonic_to_seed(&mnemonic);
|
||||
let seed = dubp_client::crypto::mnemonic::mnemonic_to_seed(&mnemonic);
|
||||
let keypair = KeyPairFromSeed32Generator::generate(seed);
|
||||
Ok(keypair.public_key().to_base58())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
// 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::*;
|
||||
use dubp_client::wallet::prelude::*;
|
||||
use dubp_client::{GvaClient, NaiveGvaClient};
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(super) fn simple_payment(
|
||||
account_index: u32,
|
||||
amount: f64,
|
||||
currency: Currency,
|
||||
dewif: &str,
|
||||
gva_endpoint: &str,
|
||||
secret_code: &str,
|
||||
recipient: &str,
|
||||
tx_comment: Option<String>,
|
||||
) -> Result<(), DubpError> {
|
||||
let keypair = crate::dewif::bip32::get_bip32_keypair(
|
||||
account_index,
|
||||
None,
|
||||
currency,
|
||||
dewif,
|
||||
None,
|
||||
secret_code,
|
||||
)?;
|
||||
|
||||
let gva_client = NaiveGvaClient::new(gva_endpoint).expect("invalid' endpoint");
|
||||
|
||||
let amount = dubp_client::Amount::Uds(amount);
|
||||
|
||||
let recipient = if let Ok(pubkey) = PublicKey::from_base58(recipient) {
|
||||
WalletScriptV10::single_sig(pubkey)
|
||||
} else {
|
||||
dubp_client::documents_parser::wallet_script_from_str(recipient)
|
||||
.map_err(DubpError::InvalidScript)?
|
||||
};
|
||||
|
||||
let res = match keypair.generate_signator() {
|
||||
dubp_client::crypto::keys::SignatorEnum::Ed25519(signator) => gva_client
|
||||
.simple_payment(amount, &signator, recipient, tx_comment, None)
|
||||
.map_err(DubpError::GvaClientError)?,
|
||||
dubp_client::crypto::keys::SignatorEnum::Schnorr() => unreachable!(),
|
||||
dubp_client::crypto::keys::SignatorEnum::Bip32Ed25519(signator) => gva_client
|
||||
.simple_payment(amount, &signator, recipient, tx_comment, None)
|
||||
.map_err(DubpError::GvaClientError)?,
|
||||
};
|
||||
|
||||
if let dubp_client::PaymentResult::Errors(errors) = res {
|
||||
Err(DubpError::PaymentError(format!("{:?}", errors)))
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
|
@ -67,7 +67,7 @@ pub(crate) fn is_ascii_letters(secret_code: &str) -> bool {
|
|||
}
|
||||
|
||||
fn gen_random_digits(n: usize) -> Result<String, DubpError> {
|
||||
let mut digits_string = dup_crypto::rand::gen_u32()
|
||||
let mut digits_string = dubp_client::crypto::rand::gen_u32()
|
||||
.map_err(|_| DubpError::RandErr)?
|
||||
.to_string();
|
||||
digits_string.truncate(n);
|
||||
|
@ -97,7 +97,7 @@ fn gen_random_letters(mut n: usize) -> Result<String, DubpError> {
|
|||
}
|
||||
|
||||
fn gen_random_letters_inner(n: usize) -> Result<String, DubpError> {
|
||||
let mut i = dup_crypto::rand::gen_u32().map_err(|_| DubpError::RandErr)?;
|
||||
let mut i = dubp_client::crypto::rand::gen_u32().map_err(|_| DubpError::RandErr)?;
|
||||
let mut letters = String::new();
|
||||
|
||||
for _ in 0..n {
|
||||
|
|
|
@ -399,6 +399,35 @@ class DubpRust {
|
|||
return completer.future;
|
||||
}
|
||||
|
||||
/// Make a simple payment from a transparent account
|
||||
static Future<void> simplePaymentFromTransparentAccount(
|
||||
{int accountIndex,
|
||||
double amount,
|
||||
String currency = "g1",
|
||||
String dewif,
|
||||
String gvaEndpoint,
|
||||
String recipient,
|
||||
String secretCode,
|
||||
String txComment}) {
|
||||
final completer = Completer<void>();
|
||||
final sendPort =
|
||||
singleCompletePort<void, String>(completer, callback: _handleErrVoid);
|
||||
|
||||
native.simple_payment_bip32(
|
||||
sendPort.nativePort,
|
||||
accountIndex,
|
||||
amount,
|
||||
StringUtf8Pointer(currency).toNativeUtf8(),
|
||||
StringUtf8Pointer(dewif).toNativeUtf8(),
|
||||
StringUtf8Pointer(gvaEndpoint).toNativeUtf8(),
|
||||
StringUtf8Pointer(recipient).toNativeUtf8(),
|
||||
StringUtf8Pointer(secretCode).toNativeUtf8(),
|
||||
StringUtf8Pointer(txComment).toNativeUtf8(),
|
||||
);
|
||||
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
static Pointer<Uint32> _listIntToPtrUint32(List<int> list) {
|
||||
final listUint32 = list.map((i) => i.toUnsigned(31)).toList();
|
||||
final Pointer<Uint32> ptr = malloc.allocate(listUint32.length);
|
||||
|
|
Loading…
Reference in New Issue