API: get_available_addrs
This commit is contained in:
parent
dbaa1c02c9
commit
8a2f2b7fea
|
@ -226,6 +226,8 @@ struct CResult_u8 convert_to_watchonly(uint8_t coin, uint32_t id_account);
|
|||
|
||||
struct CResult______u8 get_backup(uint8_t coin, uint32_t id_account);
|
||||
|
||||
struct CResult_u8 get_available_addrs(uint8_t coin, uint32_t account);
|
||||
|
||||
struct CResult_____c_char get_address(uint8_t coin, uint32_t id_account, uint8_t ua_type);
|
||||
|
||||
void import_transparent_key(uint8_t coin, uint32_t id_account, char *path);
|
||||
|
|
|
@ -3,9 +3,7 @@
|
|||
// Account creation
|
||||
|
||||
use crate::coinconfig::CoinConfig;
|
||||
use crate::db::data_generated::fb::{
|
||||
BackupT, KeyPackT, AddressBalanceVecT, AddressBalanceT,
|
||||
};
|
||||
use crate::db::data_generated::fb::{AddressBalanceT, AddressBalanceVecT, BackupT, KeyPackT};
|
||||
use crate::db::AccountData;
|
||||
use crate::key2::decode_key;
|
||||
use crate::orchard::OrchardKeyBytes;
|
||||
|
@ -265,22 +263,39 @@ pub async fn get_taddr_balance(coin: u8, id_account: u32) -> anyhow::Result<u64>
|
|||
/// is exceeded and no balance was found
|
||||
/// # Arguments
|
||||
/// * `gap_limit`: number of accounts with 0 balance before the scan stops
|
||||
pub async fn scan_transparent_accounts(coin: u8, account: u32, gap_limit: usize) -> anyhow::Result<AddressBalanceVecT> {
|
||||
pub async fn scan_transparent_accounts(
|
||||
coin: u8,
|
||||
account: u32,
|
||||
gap_limit: usize,
|
||||
) -> anyhow::Result<AddressBalanceVecT> {
|
||||
let c = CoinConfig::get(coin);
|
||||
let db = c.db()?;
|
||||
let account_data = db.get_account_info(account)?;
|
||||
let AccountData {
|
||||
seed, aindex, ..
|
||||
} = account_data;
|
||||
let AccountData { seed, aindex, .. } = account_data;
|
||||
let mut addresses = vec![];
|
||||
if let Some(seed) = seed {
|
||||
let mut client = c.connect_lwd().await?;
|
||||
addresses.extend(crate::taddr::scan_transparent_accounts(c.chain.network(), &mut client, &seed, aindex, gap_limit).await?);
|
||||
addresses.extend(
|
||||
crate::taddr::scan_transparent_accounts(
|
||||
c.chain.network(),
|
||||
&mut client,
|
||||
&seed,
|
||||
aindex,
|
||||
gap_limit,
|
||||
)
|
||||
.await?,
|
||||
);
|
||||
}
|
||||
let addresses: Vec<_> = addresses.iter().map(|a| AddressBalanceT { index: a.index,
|
||||
address: Some(a.address.clone()), balance: a.balance }).collect();
|
||||
let addresses: Vec<_> = addresses
|
||||
.iter()
|
||||
.map(|a| AddressBalanceT {
|
||||
index: a.index,
|
||||
address: Some(a.address.clone()),
|
||||
balance: a.balance,
|
||||
})
|
||||
.collect();
|
||||
let addresses = AddressBalanceVecT {
|
||||
values: Some(addresses)
|
||||
values: Some(addresses),
|
||||
};
|
||||
Ok(addresses)
|
||||
}
|
||||
|
|
|
@ -20,6 +20,13 @@ static mut POST_COBJ: Option<ffi::DartPostCObjectFnType> = None;
|
|||
|
||||
const MAX_COINS: u8 = 2;
|
||||
|
||||
fn with_coin<T, F: Fn(&Connection) -> anyhow::Result<T>>(coin: u8, f: F) -> anyhow::Result<T> {
|
||||
let c = CoinConfig::get(coin);
|
||||
let db = c.db()?;
|
||||
let connection = &db.connection;
|
||||
f(connection)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn dummy_export() {}
|
||||
|
||||
|
@ -255,6 +262,15 @@ pub unsafe extern "C" fn get_backup(coin: u8, id_account: u32) -> CResult<*const
|
|||
to_cresult_bytes(res())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_available_addrs(coin: u8, account: u32) -> CResult<u8> {
|
||||
let res = |connection: &Connection| {
|
||||
let res = crate::db::read::get_available_addrs(connection, account)?;
|
||||
Ok(res)
|
||||
};
|
||||
to_cresult(with_coin(coin, res))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_address(
|
||||
coin: u8,
|
||||
|
@ -507,9 +523,15 @@ pub async unsafe extern "C" fn shield_taddr(
|
|||
|
||||
#[tokio::main]
|
||||
#[no_mangle]
|
||||
pub async unsafe extern "C" fn scan_transparent_accounts(coin: u8, account: u32, gap_limit: u32) -> CResult<*const u8> {
|
||||
pub async unsafe extern "C" fn scan_transparent_accounts(
|
||||
coin: u8,
|
||||
account: u32,
|
||||
gap_limit: u32,
|
||||
) -> CResult<*const u8> {
|
||||
let res = async {
|
||||
let addresses = crate::api::account::scan_transparent_accounts(coin, account, gap_limit as usize).await?;
|
||||
let addresses =
|
||||
crate::api::account::scan_transparent_accounts(coin, account, gap_limit as usize)
|
||||
.await?;
|
||||
let mut builder = FlatBufferBuilder::new();
|
||||
let root = addresses.pack(&mut builder);
|
||||
builder.finish(root, None);
|
||||
|
@ -877,13 +899,6 @@ pub unsafe extern "C" fn clear_tx_details(coin: u8, account: u32) -> CResult<u8>
|
|||
to_cresult(with_coin(coin, res))
|
||||
}
|
||||
|
||||
fn with_coin<T, F: Fn(&Connection) -> anyhow::Result<T>>(coin: u8, f: F) -> anyhow::Result<T> {
|
||||
let c = CoinConfig::get(coin);
|
||||
let db = c.db()?;
|
||||
let connection = &db.connection;
|
||||
f(connection)
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_account_list(coin: u8) -> CResult<*const u8> {
|
||||
let res = |connection: &Connection| {
|
||||
|
@ -1142,10 +1157,7 @@ pub unsafe extern "C" fn clone_db_with_passwd(
|
|||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn get_property(
|
||||
coin: u8,
|
||||
name: *mut c_char,
|
||||
) -> CResult<*mut c_char> {
|
||||
pub unsafe extern "C" fn get_property(coin: u8, name: *mut c_char) -> CResult<*mut c_char> {
|
||||
from_c_str!(name);
|
||||
let res = |connection: &Connection| {
|
||||
let value = crate::db::read::get_property(connection, &name)?;
|
||||
|
|
|
@ -1131,10 +1131,7 @@ impl DbAdapter {
|
|||
"UPDATE transactions SET address = NULL, memo = NULL WHERE account = ?1",
|
||||
[account],
|
||||
)?;
|
||||
connection.execute(
|
||||
"DELETE FROM messages WHERE account = ?1",
|
||||
[account],
|
||||
)?;
|
||||
connection.execute("DELETE FROM messages WHERE account = ?1", [account])?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
@ -294,7 +294,8 @@ pub fn get_messages(network: &Network, connection: &Connection, id: u32) -> Resu
|
|||
let mut stmt = connection.prepare(
|
||||
"SELECT m.id, m.id_tx, m.timestamp, m.sender, m.recipient, m.incoming, \
|
||||
subject, body, height, read FROM messages m \
|
||||
WHERE account = ?1 ORDER BY timestamp DESC")?;
|
||||
WHERE account = ?1 ORDER BY timestamp DESC",
|
||||
)?;
|
||||
let rows = stmt.query_map(params![id], |row| {
|
||||
let id_msg: u32 = row.get("id")?;
|
||||
let id_tx: Option<u32> = row.get("id_tx")?;
|
||||
|
@ -329,7 +330,9 @@ pub fn get_messages(network: &Network, connection: &Connection, id: u32) -> Resu
|
|||
for r in rows {
|
||||
messages.push(r?);
|
||||
}
|
||||
let messages = MessageVecT { messages: Some(messages) };
|
||||
let messages = MessageVecT {
|
||||
messages: Some(messages),
|
||||
};
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
|
@ -660,15 +663,48 @@ pub fn resolve_addresses(
|
|||
}
|
||||
|
||||
pub fn get_property(connection: &Connection, name: &str) -> anyhow::Result<String> {
|
||||
let url = connection.query_row("SELECT value FROM properties WHERE name = ?1", [name], |row| {
|
||||
let url = connection
|
||||
.query_row(
|
||||
"SELECT value FROM properties WHERE name = ?1",
|
||||
[name],
|
||||
|row| {
|
||||
let url: String = row.get(0)?;
|
||||
Ok(url)
|
||||
}).optional()?;
|
||||
},
|
||||
)
|
||||
.optional()?;
|
||||
Ok(url.unwrap_or(String::new()))
|
||||
}
|
||||
|
||||
pub fn set_property(connection: &Connection, name: &str, value: &str) -> anyhow::Result<()> {
|
||||
connection.execute("INSERT INTO properties(name, value) VALUES (?1, ?2) ON CONFLICT (name) \
|
||||
DO UPDATE SET value = excluded.value", params![name, value])?;
|
||||
connection.execute(
|
||||
"INSERT INTO properties(name, value) VALUES (?1, ?2) ON CONFLICT (name) \
|
||||
DO UPDATE SET value = excluded.value",
|
||||
params![name, value],
|
||||
)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_available_addrs(connection: &Connection, account: u32) -> anyhow::Result<u8> {
|
||||
let has_transparent = connection
|
||||
.query_row(
|
||||
"SELECT 1 FROM taddrs WHERE account = ?1",
|
||||
[account],
|
||||
|_row| Ok(()),
|
||||
)
|
||||
.optional()?
|
||||
.is_some();
|
||||
let has_sapling = true;
|
||||
let has_orchard = connection
|
||||
.query_row(
|
||||
"SELECT 1 FROM orchard_addrs WHERE account = ?1",
|
||||
[account],
|
||||
|_row| Ok(()),
|
||||
)
|
||||
.optional()?
|
||||
.is_some();
|
||||
let res = if has_transparent { 1 } else { 0 }
|
||||
| if has_sapling { 2 } else { 0 }
|
||||
| if has_orchard { 4 } else { 0 };
|
||||
Ok(res)
|
||||
}
|
||||
|
|
25
src/taddr.rs
25
src/taddr.rs
|
@ -1,14 +1,14 @@
|
|||
use crate::api::payment_v2::build_tx_plan_with_utxos;
|
||||
use crate::api::recipient::RecipientMemo;
|
||||
use crate::chain::{get_checkpoint_height, EXPIRY_HEIGHT_OFFSET, get_latest_height};
|
||||
use crate::chain::{get_checkpoint_height, get_latest_height, EXPIRY_HEIGHT_OFFSET};
|
||||
use crate::coinconfig::CoinConfig;
|
||||
use crate::db::AccountData;
|
||||
use crate::key2::split_key;
|
||||
use crate::note_selection::{SecretKeys, Source, UTXO};
|
||||
use crate::unified::orchard_as_unified;
|
||||
use crate::{
|
||||
broadcast_tx, build_tx, AddressList, BlockId, CompactTxStreamerClient, GetAddressUtxosArg,
|
||||
GetAddressUtxosReply, Hash, TransparentAddressBlockFilter, TxFilter, BlockRange,
|
||||
broadcast_tx, build_tx, AddressList, BlockId, BlockRange, CompactTxStreamerClient,
|
||||
GetAddressUtxosArg, GetAddressUtxosReply, Hash, TransparentAddressBlockFilter, TxFilter,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use base58check::FromBase58Check;
|
||||
|
@ -25,7 +25,7 @@ use tonic::transport::Channel;
|
|||
use tonic::Request;
|
||||
use zcash_client_backend::encoding::encode_transparent_address;
|
||||
use zcash_params::coin::get_branch;
|
||||
use zcash_primitives::consensus::{Network, Parameters, NetworkUpgrade};
|
||||
use zcash_primitives::consensus::{Network, NetworkUpgrade, Parameters};
|
||||
use zcash_primitives::legacy::TransparentAddress;
|
||||
use zcash_primitives::memo::Memo;
|
||||
use zcash_primitives::transaction::components::OutPoint;
|
||||
|
@ -178,12 +178,23 @@ pub async fn scan_transparent_accounts(
|
|||
mut aindex: u32,
|
||||
gap_limit: usize,
|
||||
) -> anyhow::Result<Vec<TBalance>> {
|
||||
let start: u32 = network.activation_height(NetworkUpgrade::Sapling).unwrap().into();
|
||||
let start: u32 = network
|
||||
.activation_height(NetworkUpgrade::Sapling)
|
||||
.unwrap()
|
||||
.into();
|
||||
let end = get_latest_height(client).await?;
|
||||
|
||||
let range = BlockRange {
|
||||
start: Some(BlockId { height: start as u64, hash: vec![] }),
|
||||
end: Some(BlockId { height: end as u64, hash: vec![] }), spam_filter_threshold: 0 };
|
||||
start: Some(BlockId {
|
||||
height: start as u64,
|
||||
hash: vec![],
|
||||
}),
|
||||
end: Some(BlockId {
|
||||
height: end as u64,
|
||||
hash: vec![],
|
||||
}),
|
||||
spam_filter_threshold: 0,
|
||||
};
|
||||
|
||||
let mut addresses = vec![];
|
||||
let mut gap = 0;
|
||||
|
|
Loading…
Reference in New Issue