2022-06-08 05:48:16 -07:00
|
|
|
use crate::coinconfig::{init_coin, CoinConfig};
|
2022-11-12 17:39:12 -08:00
|
|
|
use crate::note_selection::TransactionReport;
|
|
|
|
use crate::{ChainError, TransactionPlan, Tx};
|
2022-06-08 05:48:16 -07:00
|
|
|
use allo_isolate::{ffi, IntoDart};
|
|
|
|
use android_logger::Config;
|
2022-09-22 01:55:32 -07:00
|
|
|
use anyhow::anyhow;
|
2022-06-08 05:48:16 -07:00
|
|
|
use lazy_static::lazy_static;
|
|
|
|
use log::Level;
|
2022-06-22 06:03:49 -07:00
|
|
|
use std::cell::RefCell;
|
2022-06-08 05:48:16 -07:00
|
|
|
use std::ffi::{CStr, CString};
|
|
|
|
use std::os::raw::c_char;
|
|
|
|
use std::sync::Mutex;
|
2022-06-22 08:11:19 -07:00
|
|
|
use tokio::sync::Semaphore;
|
2022-06-08 05:48:16 -07:00
|
|
|
use zcash_primitives::transaction::builder::Progress;
|
|
|
|
|
|
|
|
static mut POST_COBJ: Option<ffi::DartPostCObjectFnType> = None;
|
|
|
|
|
2022-09-10 18:33:04 -07:00
|
|
|
const MAX_COINS: u8 = 3;
|
|
|
|
|
2022-06-22 06:03:49 -07:00
|
|
|
lazy_static! {
|
|
|
|
static ref LAST_ERROR: Mutex<RefCell<String>> = Mutex::new(RefCell::new(String::new()));
|
|
|
|
}
|
|
|
|
|
2022-06-09 04:28:37 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn dummy_export() {}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn dart_post_cobject(ptr: ffi::DartPostCObjectFnType) {
|
|
|
|
POST_COBJ = Some(ptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
macro_rules! from_c_str {
|
|
|
|
($v: ident) => {
|
|
|
|
let $v = CStr::from_ptr($v).to_string_lossy();
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_c_str(s: String) -> *mut c_char {
|
|
|
|
CString::new(s).unwrap().into_raw()
|
|
|
|
}
|
|
|
|
|
2022-09-22 01:55:32 -07:00
|
|
|
fn to_cresult<T>(res: Result<T, anyhow::Error>) -> CResult<T> {
|
|
|
|
let res = res.map_err(|e| e.to_string());
|
|
|
|
match res {
|
|
|
|
Ok(v) => CResult {
|
|
|
|
value: v,
|
|
|
|
error: std::ptr::null_mut::<c_char>(),
|
|
|
|
},
|
|
|
|
Err(e) => {
|
|
|
|
log::error!("{}", e);
|
|
|
|
CResult {
|
|
|
|
value: unsafe { std::mem::zeroed() },
|
|
|
|
error: to_c_str(e),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn to_cresult_str(res: Result<String, anyhow::Error>) -> CResult<*mut c_char> {
|
|
|
|
let res = res.map(to_c_str);
|
|
|
|
to_cresult(res)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn log_error(res: Result<(), anyhow::Error>) {
|
|
|
|
if let Err(e) = res {
|
|
|
|
log::error!("{}", e.to_string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-22 06:03:49 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn deallocate_str(s: *mut c_char) {
|
|
|
|
let _ = CString::from_raw(s);
|
|
|
|
}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
fn try_init_logger() {
|
|
|
|
android_logger::init_once(
|
|
|
|
Config::default()
|
|
|
|
// .format(|buf, record| {
|
|
|
|
// writeln!(
|
|
|
|
// buf,
|
|
|
|
// "{:?}-{:?}: {}",
|
|
|
|
// record.file(),
|
|
|
|
// record.line(),
|
|
|
|
// record.args()
|
|
|
|
// )
|
|
|
|
// })
|
|
|
|
.with_min_level(Level::Info),
|
|
|
|
);
|
2022-08-16 19:56:10 -07:00
|
|
|
let _ = env_logger::try_init();
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
2022-09-22 01:55:32 -07:00
|
|
|
#[repr(C)]
|
|
|
|
pub struct CResult<T> {
|
|
|
|
value: T,
|
|
|
|
error: *mut c_char,
|
|
|
|
}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn init_wallet(db_path: *mut c_char) {
|
|
|
|
try_init_logger();
|
|
|
|
from_c_str!(db_path);
|
2022-11-13 01:00:21 -08:00
|
|
|
let _ = init_coin(0, &format!("{}/zec-test.db", &db_path));
|
2022-06-08 05:48:16 -07:00
|
|
|
let _ = init_coin(1, &format!("{}/yec.db", &db_path));
|
2022-09-09 08:08:49 -07:00
|
|
|
let _ = init_coin(2, &format!("{}/arrr.db", &db_path));
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn set_active(active: u8) {
|
|
|
|
crate::coinconfig::set_active(active);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn set_active_account(coin: u8, id: u32) {
|
|
|
|
crate::coinconfig::set_active_account(coin, id);
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn set_coin_lwd_url(coin: u8, lwd_url: *mut c_char) {
|
|
|
|
from_c_str!(lwd_url);
|
|
|
|
crate::coinconfig::set_coin_lwd_url(coin, &lwd_url);
|
|
|
|
}
|
|
|
|
|
2022-07-14 18:12:25 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn get_lwd_url(coin: u8) -> *mut c_char {
|
|
|
|
let server = crate::coinconfig::get_coin_lwd_url(coin);
|
|
|
|
to_c_str(server)
|
|
|
|
}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn reset_app() {
|
|
|
|
let res = || {
|
2022-10-27 03:10:51 -07:00
|
|
|
for i in 0..MAX_COINS {
|
|
|
|
crate::api::account::reset_db(i)?;
|
|
|
|
}
|
2022-06-08 05:48:16 -07:00
|
|
|
Ok(())
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res())
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn new_account(
|
|
|
|
coin: u8,
|
|
|
|
name: *mut c_char,
|
|
|
|
data: *mut c_char,
|
|
|
|
index: i32,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<u32> {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(name);
|
|
|
|
from_c_str!(data);
|
|
|
|
let data = if !data.is_empty() {
|
|
|
|
Some(data.to_string())
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
let index = if index >= 0 { Some(index as u32) } else { None };
|
|
|
|
let res = crate::api::account::new_account(coin, &name, data, index);
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-07-14 18:12:25 -07:00
|
|
|
pub unsafe extern "C" fn new_sub_account(name: *mut c_char, index: i32, count: u32) {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(name);
|
|
|
|
let index = if index >= 0 { Some(index as u32) } else { None };
|
2022-07-14 18:12:25 -07:00
|
|
|
let res = crate::api::account::new_sub_account(&name, index, count);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
2022-11-12 17:39:12 -08:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn get_address(
|
|
|
|
coin: u8,
|
|
|
|
id_account: u32,
|
|
|
|
ua_type: u8,
|
|
|
|
) -> CResult<*mut c_char> {
|
|
|
|
let address = crate::api::account::get_address(coin, id_account, ua_type);
|
|
|
|
to_cresult_str(address)
|
|
|
|
}
|
|
|
|
|
2022-07-16 20:23:56 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn import_transparent_key(coin: u8, id_account: u32, path: *mut c_char) {
|
|
|
|
from_c_str!(path);
|
|
|
|
let res = crate::api::account::import_transparent_key(coin, id_account, &path);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-07-16 20:23:56 -07:00
|
|
|
}
|
|
|
|
|
2022-07-23 06:25:08 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn import_transparent_secret_key(
|
|
|
|
coin: u8,
|
|
|
|
id_account: u32,
|
|
|
|
secret_key: *mut c_char,
|
|
|
|
) {
|
|
|
|
from_c_str!(secret_key);
|
|
|
|
let res = crate::api::account::import_transparent_secret_key(coin, id_account, &secret_key);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-07-23 06:25:08 -07:00
|
|
|
}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
lazy_static! {
|
2022-06-22 08:11:19 -07:00
|
|
|
static ref SYNC_LOCK: Semaphore = Semaphore::new(1);
|
2022-08-30 07:00:15 -07:00
|
|
|
static ref SYNC_CANCELED: Mutex<bool> = Mutex::new(false);
|
2022-07-21 18:08:29 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn cancel_warp() {
|
|
|
|
log::info!("Sync canceled");
|
2022-08-30 07:00:15 -07:00
|
|
|
*SYNC_CANCELED.lock().unwrap() = true;
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-07-30 16:11:58 -07:00
|
|
|
pub async unsafe extern "C" fn warp(
|
|
|
|
coin: u8,
|
|
|
|
get_tx: bool,
|
|
|
|
anchor_offset: u32,
|
|
|
|
max_cost: u32,
|
|
|
|
port: i64,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<u8> {
|
2022-06-22 08:11:19 -07:00
|
|
|
let res = async {
|
|
|
|
let _permit = SYNC_LOCK.acquire().await?;
|
|
|
|
log::info!("Sync started");
|
2022-07-21 18:08:29 -07:00
|
|
|
let result = crate::api::sync::coin_sync(
|
|
|
|
coin,
|
|
|
|
get_tx,
|
|
|
|
anchor_offset,
|
2022-07-30 16:11:58 -07:00
|
|
|
max_cost,
|
2022-10-04 20:22:04 -07:00
|
|
|
move |progress| {
|
|
|
|
let mut progress = serde_json::to_string(&progress).unwrap().into_dart();
|
|
|
|
if port != 0 {
|
|
|
|
if let Some(p) = POST_COBJ {
|
|
|
|
p(port, &mut progress);
|
2022-07-21 18:08:29 -07:00
|
|
|
}
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
2022-07-21 18:08:29 -07:00
|
|
|
},
|
|
|
|
&SYNC_CANCELED,
|
|
|
|
)
|
2022-06-22 08:11:19 -07:00
|
|
|
.await;
|
|
|
|
log::info!("Sync finished");
|
|
|
|
|
|
|
|
crate::api::mempool::scan().await?;
|
|
|
|
|
|
|
|
match result {
|
|
|
|
Ok(_) => Ok(0),
|
|
|
|
Err(err) => {
|
|
|
|
if let Some(e) = err.downcast_ref::<ChainError>() {
|
|
|
|
match e {
|
|
|
|
ChainError::Reorg => Ok(1),
|
|
|
|
ChainError::Busy => Ok(2),
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
2022-06-22 08:11:19 -07:00
|
|
|
} else {
|
|
|
|
log::error!("{}", err);
|
|
|
|
Ok(0xFF)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
}
|
2022-06-22 08:11:19 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
let r = res.await;
|
2022-08-30 07:00:15 -07:00
|
|
|
*SYNC_CANCELED.lock().unwrap() = false;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(r)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn is_valid_key(coin: u8, key: *mut c_char) -> i8 {
|
|
|
|
from_c_str!(key);
|
|
|
|
crate::key2::is_valid_key(coin, &key)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn valid_address(coin: u8, address: *mut c_char) -> bool {
|
|
|
|
from_c_str!(address);
|
|
|
|
crate::key2::is_valid_address(coin, &address)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn new_diversified_address() -> CResult<*mut c_char> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = || crate::api::account::new_diversified_address();
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res())
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn get_latest_height() -> CResult<u32> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let height = crate::api::sync::get_latest_height().await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(height)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn report_progress(progress: Progress, port: i64) {
|
|
|
|
if port != 0 {
|
|
|
|
let progress = match progress.end() {
|
|
|
|
Some(end) => (progress.cur() * 100 / end) as i32,
|
|
|
|
None => -(progress.cur() as i32),
|
|
|
|
};
|
|
|
|
let mut progress = progress.into_dart();
|
|
|
|
unsafe {
|
|
|
|
if let Some(p) = POST_COBJ {
|
|
|
|
p(port, &mut progress);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-13 01:00:21 -08:00
|
|
|
// #[tokio::main]
|
|
|
|
// #[no_mangle]
|
|
|
|
// pub async unsafe extern "C" fn send_multi_payment(
|
|
|
|
// coin: u8,
|
|
|
|
// account: u32,
|
|
|
|
// recipients_json: *mut c_char,
|
|
|
|
// anchor_offset: u32,
|
|
|
|
// port: i64,
|
|
|
|
// ) -> CResult<*mut c_char> {
|
|
|
|
// from_c_str!(recipients_json);
|
|
|
|
// let res = async move {
|
|
|
|
// let height = crate::api::sync::get_latest_height().await?;
|
|
|
|
// let recipients = crate::api::recipient::parse_recipients(&recipients_json)?;
|
|
|
|
// let res = crate::api::payment_v2::build_sign_send_multi_payment(
|
|
|
|
// coin,
|
|
|
|
// account,
|
|
|
|
// height,
|
|
|
|
// &recipients,
|
|
|
|
// anchor_offset,
|
|
|
|
// Box::new(move |progress| {
|
|
|
|
// report_progress(progress, port);
|
|
|
|
// }),
|
|
|
|
// )
|
|
|
|
// .await?;
|
|
|
|
// Ok(res)
|
|
|
|
// };
|
|
|
|
// to_cresult_str(res.await)
|
|
|
|
// }
|
2022-06-08 05:48:16 -07:00
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn skip_to_last_height(coin: u8) {
|
|
|
|
let res = crate::api::sync::skip_to_last_height(coin).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn rewind_to(height: u32) -> CResult<u32> {
|
2022-09-06 19:38:16 -07:00
|
|
|
let res = crate::api::sync::rewind_to(height).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-09-06 19:38:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn rescan_from(height: u32) {
|
|
|
|
let res = crate::api::sync::rescan_from(height).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn mempool_sync() -> CResult<i64> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = crate::api::mempool::scan().await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn mempool_reset() {
|
|
|
|
let c = CoinConfig::get_active();
|
|
|
|
let mut mempool = c.mempool.lock().unwrap();
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(mempool.clear());
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn get_mempool_balance() -> i64 {
|
|
|
|
let c = CoinConfig::get_active();
|
|
|
|
let mempool = c.mempool.lock().unwrap();
|
|
|
|
mempool.get_unconfirmed_balance()
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn get_taddr_balance(coin: u8, id_account: u32) -> CResult<u64> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = if coin == 0xFF {
|
|
|
|
crate::api::account::get_taddr_balance_default().await
|
|
|
|
} else {
|
|
|
|
crate::api::account::get_taddr_balance(coin, id_account).await
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-11-12 17:39:12 -08:00
|
|
|
pub async unsafe extern "C" fn shield_taddr(coin: u8, account: u32) -> CResult<*mut c_char> {
|
|
|
|
let res = crate::api::payment_v2::shield_taddr(coin, account).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn scan_transparent_accounts(gap_limit: u32) {
|
|
|
|
let res = crate::api::account::scan_transparent_accounts(gap_limit as usize).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn prepare_multi_payment(
|
2022-11-12 17:39:12 -08:00
|
|
|
coin: u8,
|
|
|
|
account: u32,
|
2022-06-08 05:48:16 -07:00
|
|
|
recipients_json: *mut c_char,
|
|
|
|
anchor_offset: u32,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<*mut c_char> {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(recipients_json);
|
|
|
|
let res = async {
|
|
|
|
let last_height = crate::api::sync::get_latest_height().await?;
|
2022-11-12 17:39:12 -08:00
|
|
|
let recipients = crate::api::recipient::parse_recipients(&recipients_json)?;
|
|
|
|
let tx = crate::api::payment_v2::build_tx_plan(
|
|
|
|
coin,
|
|
|
|
account,
|
2022-06-08 05:48:16 -07:00
|
|
|
last_height,
|
|
|
|
&recipients,
|
|
|
|
anchor_offset,
|
2022-06-16 03:13:58 -07:00
|
|
|
)
|
|
|
|
.await?;
|
2022-06-10 22:40:32 -07:00
|
|
|
let tx_str = serde_json::to_string(&tx)?;
|
|
|
|
Ok(tx_str)
|
2022-06-08 05:48:16 -07:00
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res.await)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
2022-11-12 17:39:12 -08:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn transaction_report(coin: u8, plan: *mut c_char) -> CResult<*mut c_char> {
|
|
|
|
from_c_str!(plan);
|
|
|
|
let c = CoinConfig::get(coin);
|
|
|
|
let res = || {
|
|
|
|
let plan: TransactionPlan = serde_json::from_str(&plan)?;
|
|
|
|
let report = TransactionReport::from_plan(c.chain.network(), plan);
|
|
|
|
let report = serde_json::to_string(&report)?;
|
|
|
|
Ok(report)
|
|
|
|
};
|
|
|
|
to_cresult_str(res())
|
|
|
|
}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-11-12 17:39:12 -08:00
|
|
|
pub async unsafe extern "C" fn sign(
|
|
|
|
coin: u8,
|
|
|
|
account: u32,
|
|
|
|
tx: *mut c_char,
|
|
|
|
port: i64,
|
|
|
|
) -> CResult<*mut c_char> {
|
2022-06-20 02:05:11 -07:00
|
|
|
from_c_str!(tx);
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = async {
|
2022-11-12 17:39:12 -08:00
|
|
|
let tx: TransactionPlan = serde_json::from_str(&tx)?;
|
|
|
|
let raw_tx = crate::api::payment_v2::sign_plan(coin, account, &tx)?;
|
2022-06-20 02:05:11 -07:00
|
|
|
let tx_str = base64::encode(&raw_tx);
|
2022-09-22 01:55:32 -07:00
|
|
|
Ok::<_, anyhow::Error>(tx_str)
|
2022-06-08 05:48:16 -07:00
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
let res = res.await;
|
2022-11-12 17:39:12 -08:00
|
|
|
to_cresult_str(res)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn sign_and_broadcast(
|
|
|
|
coin: u8,
|
|
|
|
account: u32,
|
|
|
|
tx_plan: *mut c_char,
|
|
|
|
) -> CResult<*mut c_char> {
|
|
|
|
from_c_str!(tx_plan);
|
|
|
|
let res = async {
|
|
|
|
let tx_plan: TransactionPlan = serde_json::from_str(&tx_plan)?;
|
|
|
|
let txid = crate::api::payment_v2::sign_and_broadcast(coin, account, &tx_plan).await?;
|
|
|
|
Ok::<_, anyhow::Error>(txid)
|
|
|
|
};
|
|
|
|
let res = res.await;
|
|
|
|
to_cresult_str(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn broadcast_tx(tx_str: *mut c_char) -> CResult<*mut c_char> {
|
2022-06-20 02:05:11 -07:00
|
|
|
from_c_str!(tx_str);
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = async {
|
2022-06-20 02:05:11 -07:00
|
|
|
let tx = base64::decode(&*tx_str)?;
|
|
|
|
crate::broadcast_tx(&tx).await
|
2022-06-08 05:48:16 -07:00
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res.await)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn get_activation_date() -> CResult<u32> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = crate::api::sync::get_activation_date().await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn get_block_by_time(time: u32) -> CResult<u32> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = crate::api::sync::get_block_by_time(time).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn sync_historical_prices(
|
|
|
|
now: i64,
|
|
|
|
days: u32,
|
|
|
|
currency: *mut c_char,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<u32> {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(currency);
|
|
|
|
let res = crate::api::historical_prices::sync_historical_prices(now, days, ¤cy).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn store_contact(
|
|
|
|
id: u32,
|
|
|
|
name: *mut c_char,
|
|
|
|
address: *mut c_char,
|
|
|
|
dirty: bool,
|
|
|
|
) {
|
|
|
|
from_c_str!(name);
|
|
|
|
from_c_str!(address);
|
|
|
|
let res = crate::api::contact::store_contact(id, &name, &address, dirty);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub async unsafe extern "C" fn commit_unsaved_contacts(anchor_offset: u32) -> CResult<*mut c_char> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let res = crate::api::contact::commit_unsaved_contacts(anchor_offset).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn mark_message_read(message: u32, read: bool) {
|
|
|
|
let res = crate::api::message::mark_message_read(message, read);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn mark_all_messages_read(read: bool) {
|
|
|
|
let res = crate::api::message::mark_all_messages_read(read);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn truncate_data() {
|
|
|
|
let res = crate::api::account::truncate_data();
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
2022-09-02 01:44:31 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn truncate_sync_data() {
|
|
|
|
let res = crate::api::account::truncate_sync_data();
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-09-02 01:44:31 -07:00
|
|
|
}
|
|
|
|
|
2022-06-08 05:48:16 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn delete_account(coin: u8, account: u32) {
|
|
|
|
let res = crate::api::account::delete_account(coin, account);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn make_payment_uri(
|
|
|
|
address: *mut c_char,
|
|
|
|
amount: u64,
|
|
|
|
memo: *mut c_char,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<*mut c_char> {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(memo);
|
|
|
|
from_c_str!(address);
|
|
|
|
let res = crate::api::payment_uri::make_payment_uri(&address, amount, &memo);
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res)
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn parse_payment_uri(uri: *mut c_char) -> CResult<*mut c_char> {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(uri);
|
2022-06-10 11:41:05 -07:00
|
|
|
let payment_json = || {
|
|
|
|
let payment = crate::api::payment_uri::parse_payment_uri(&uri)?;
|
|
|
|
let payment_json = serde_json::to_string(&payment)?;
|
|
|
|
Ok(payment_json)
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(payment_json())
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn generate_random_enc_key() -> CResult<*mut c_char> {
|
2022-10-19 23:24:36 -07:00
|
|
|
to_cresult_str(crate::api::fullbackup::generate_random_enc_key())
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn get_full_backup(key: *mut c_char) -> CResult<*mut c_char> {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(key);
|
|
|
|
let res = || {
|
|
|
|
let mut accounts = vec![];
|
2022-09-10 18:33:04 -07:00
|
|
|
for coin in 0..MAX_COINS {
|
2022-06-08 05:48:16 -07:00
|
|
|
accounts.extend(crate::api::fullbackup::get_full_backup(coin)?);
|
|
|
|
}
|
|
|
|
|
|
|
|
let backup = crate::api::fullbackup::encrypt_backup(&accounts, &key)?;
|
|
|
|
Ok(backup)
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res())
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-06-22 06:03:49 -07:00
|
|
|
pub unsafe extern "C" fn restore_full_backup(key: *mut c_char, backup: *mut c_char) {
|
2022-06-08 05:48:16 -07:00
|
|
|
from_c_str!(key);
|
|
|
|
from_c_str!(backup);
|
|
|
|
let res = || {
|
|
|
|
let accounts = crate::api::fullbackup::decrypt_backup(&key, &backup)?;
|
2022-09-10 18:33:04 -07:00
|
|
|
for coin in 0..MAX_COINS {
|
2022-06-08 05:48:16 -07:00
|
|
|
crate::api::fullbackup::restore_full_backup(coin, &accounts)?;
|
|
|
|
}
|
2022-06-22 06:03:49 -07:00
|
|
|
Ok(())
|
2022-06-08 05:48:16 -07:00
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res())
|
2022-06-08 05:48:16 -07:00
|
|
|
}
|
2022-06-20 02:05:11 -07:00
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn split_data(id: u32, data: *mut c_char) -> CResult<*mut c_char> {
|
2022-06-20 02:05:11 -07:00
|
|
|
from_c_str!(data);
|
|
|
|
let res = || {
|
2022-10-19 23:24:36 -07:00
|
|
|
let res = crate::fountain::FountainCodes::encode_into_drops(id, &base64::decode(&*data)?)?;
|
2022-06-20 02:05:11 -07:00
|
|
|
let output = serde_json::to_string(&res)?;
|
|
|
|
Ok(output)
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res())
|
2022-06-20 02:05:11 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn merge_data(drop: *mut c_char) -> CResult<*mut c_char> {
|
2022-06-20 02:05:11 -07:00
|
|
|
from_c_str!(drop);
|
|
|
|
let res = || {
|
2022-10-19 23:32:11 -07:00
|
|
|
let res = crate::fountain::RaptorQDrops::put_drop(&*drop)?
|
2022-06-20 02:05:11 -07:00
|
|
|
.map(|d| base64::encode(&d))
|
|
|
|
.unwrap_or(String::new());
|
|
|
|
Ok::<_, anyhow::Error>(res)
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
let res = res().or(Ok(String::new()));
|
|
|
|
to_cresult_str(res)
|
2022-06-20 02:05:11 -07:00
|
|
|
}
|
2022-06-21 17:18:47 -07:00
|
|
|
|
|
|
|
#[no_mangle]
|
2022-09-22 01:55:32 -07:00
|
|
|
pub unsafe extern "C" fn get_tx_summary(tx: *mut c_char) -> CResult<*mut c_char> {
|
2022-06-21 17:18:47 -07:00
|
|
|
from_c_str!(tx);
|
|
|
|
let res = || {
|
|
|
|
let tx: Tx = serde_json::from_str(&tx)?;
|
2022-10-19 23:24:36 -07:00
|
|
|
let summary = crate::pay::get_tx_summary(&tx)?;
|
2022-06-21 17:18:47 -07:00
|
|
|
let summary = serde_json::to_string(&summary)?;
|
|
|
|
Ok::<_, anyhow::Error>(summary)
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res())
|
2022-06-21 17:18:47 -07:00
|
|
|
}
|
2022-07-13 20:22:12 -07:00
|
|
|
|
|
|
|
#[tokio::main]
|
|
|
|
#[no_mangle]
|
|
|
|
pub async unsafe extern "C" fn get_best_server(
|
|
|
|
servers: *mut *mut c_char,
|
|
|
|
count: u32,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<*mut c_char> {
|
2022-07-13 20:22:12 -07:00
|
|
|
let mut cservers = vec![];
|
|
|
|
for i in 0..count {
|
|
|
|
let ptr = *servers.offset(i as isize);
|
|
|
|
let s = CStr::from_ptr(ptr).to_string_lossy();
|
|
|
|
cservers.push(s.to_string());
|
|
|
|
}
|
|
|
|
let best_server = crate::get_best_server(&cservers)
|
|
|
|
.await
|
2022-09-22 01:55:32 -07:00
|
|
|
.ok_or(anyhow!("No server available"));
|
|
|
|
to_cresult_str(best_server)
|
2022-07-13 20:22:12 -07:00
|
|
|
}
|
2022-07-17 19:55:57 -07:00
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn import_from_zwl(coin: u8, name: *mut c_char, data: *mut c_char) {
|
|
|
|
from_c_str!(name);
|
|
|
|
from_c_str!(data);
|
|
|
|
let res = crate::api::account::import_from_zwl(coin, &name, &data);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-07-17 19:55:57 -07:00
|
|
|
}
|
2022-07-26 19:11:36 -07:00
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn derive_zip32(
|
|
|
|
coin: u8,
|
|
|
|
id_account: u32,
|
|
|
|
account: u32,
|
|
|
|
external: u32,
|
|
|
|
has_address: bool,
|
|
|
|
address: u32,
|
2022-09-22 01:55:32 -07:00
|
|
|
) -> CResult<*mut c_char> {
|
2022-07-26 19:11:36 -07:00
|
|
|
let res = || {
|
|
|
|
let address = if has_address { Some(address) } else { None };
|
|
|
|
let kp = crate::api::account::derive_keys(coin, id_account, account, external, address)?;
|
|
|
|
let result = serde_json::to_string(&kp)?;
|
|
|
|
Ok(result)
|
|
|
|
};
|
2022-09-22 01:55:32 -07:00
|
|
|
to_cresult_str(res())
|
2022-07-26 19:11:36 -07:00
|
|
|
}
|
2022-08-13 19:56:42 -07:00
|
|
|
|
2022-08-21 09:40:14 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn disable_wal(db_path: *mut c_char) {
|
|
|
|
from_c_str!(db_path);
|
|
|
|
let res = crate::db::DbAdapter::disable_wal(&db_path);
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-08-21 09:40:14 -07:00
|
|
|
}
|
|
|
|
|
2022-08-13 19:56:42 -07:00
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn has_cuda() -> bool {
|
2022-10-19 23:24:36 -07:00
|
|
|
crate::gpu::has_cuda()
|
2022-08-13 19:56:42 -07:00
|
|
|
}
|
2022-08-18 21:07:55 -07:00
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn has_metal() -> bool {
|
2022-10-19 23:24:36 -07:00
|
|
|
crate::gpu::has_metal()
|
2022-08-18 21:07:55 -07:00
|
|
|
}
|
2022-08-21 10:48:34 -07:00
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn has_gpu() -> bool {
|
2022-10-19 23:24:36 -07:00
|
|
|
crate::gpu::has_gpu()
|
2022-08-21 10:48:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
#[no_mangle]
|
|
|
|
pub unsafe extern "C" fn use_gpu(v: bool) {
|
2022-10-19 23:24:36 -07:00
|
|
|
crate::gpu::use_gpu(v)
|
2022-08-21 10:48:34 -07:00
|
|
|
}
|
2022-08-26 05:54:52 -07:00
|
|
|
|
2022-08-26 21:43:36 -07:00
|
|
|
#[tokio::main]
|
2022-08-26 05:54:52 -07:00
|
|
|
#[no_mangle]
|
2022-08-26 21:43:36 -07:00
|
|
|
pub async unsafe extern "C" fn import_sync_file(coin: u8, path: *mut c_char) {
|
2022-08-26 05:54:52 -07:00
|
|
|
from_c_str!(path);
|
2022-08-26 21:43:36 -07:00
|
|
|
let res = crate::api::account::import_sync_data(coin, &path).await;
|
2022-09-22 01:55:32 -07:00
|
|
|
log_error(res)
|
2022-08-26 05:54:52 -07:00
|
|
|
}
|