2022-06-08 05:48:16 -07:00
|
|
|
use crate::coinconfig::CoinConfig;
|
2021-08-16 06:07:04 -07:00
|
|
|
use crate::{
|
2022-06-10 02:16:00 -07:00
|
|
|
AddressList, CompactTxStreamerClient, GetAddressUtxosArg, GetAddressUtxosReply,
|
2021-08-16 06:07:04 -07:00
|
|
|
};
|
2021-07-16 01:42:29 -07:00
|
|
|
use bip39::{Language, Mnemonic, Seed};
|
2022-06-07 09:58:24 -07:00
|
|
|
use ripemd::{Digest, Ripemd160};
|
2021-07-16 01:42:29 -07:00
|
|
|
use secp256k1::{All, PublicKey, Secp256k1, SecretKey};
|
|
|
|
use sha2::Sha256;
|
|
|
|
use tiny_hderive::bip32::ExtendedPrivKey;
|
2021-07-09 06:33:05 -07:00
|
|
|
use tonic::transport::Channel;
|
|
|
|
use tonic::Request;
|
2021-11-11 17:39:50 -08:00
|
|
|
use zcash_client_backend::encoding::encode_transparent_address;
|
2022-03-07 06:47:06 -08:00
|
|
|
use zcash_primitives::consensus::{Network, Parameters};
|
2021-11-11 17:39:50 -08:00
|
|
|
use zcash_primitives::legacy::TransparentAddress;
|
2021-07-09 06:33:05 -07:00
|
|
|
|
2021-07-16 01:42:29 -07:00
|
|
|
pub async fn get_taddr_balance(
|
|
|
|
client: &mut CompactTxStreamerClient<Channel>,
|
|
|
|
address: &str,
|
|
|
|
) -> anyhow::Result<u64> {
|
2021-07-09 06:33:05 -07:00
|
|
|
let req = AddressList {
|
|
|
|
addresses: vec![address.to_string()],
|
|
|
|
};
|
2021-07-16 01:42:29 -07:00
|
|
|
let rep = client
|
|
|
|
.get_taddress_balance(Request::new(req))
|
|
|
|
.await?
|
|
|
|
.into_inner();
|
2021-07-09 06:33:05 -07:00
|
|
|
Ok(rep.value_zat as u64)
|
|
|
|
}
|
|
|
|
|
2021-11-11 17:39:50 -08:00
|
|
|
pub async fn get_utxos(
|
|
|
|
client: &mut CompactTxStreamerClient<Channel>,
|
2022-06-08 05:48:16 -07:00
|
|
|
t_address: &str,
|
|
|
|
_account: u32,
|
2021-11-11 17:39:50 -08:00
|
|
|
) -> anyhow::Result<Vec<GetAddressUtxosReply>> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let req = GetAddressUtxosArg {
|
|
|
|
addresses: vec![t_address.to_string()],
|
|
|
|
start_height: 0,
|
|
|
|
max_entries: 0,
|
|
|
|
};
|
|
|
|
let utxo_rep = client
|
|
|
|
.get_address_utxos(Request::new(req))
|
|
|
|
.await?
|
|
|
|
.into_inner();
|
|
|
|
Ok(utxo_rep.address_utxos)
|
2021-07-09 06:33:05 -07:00
|
|
|
}
|
|
|
|
|
2022-06-07 09:58:24 -07:00
|
|
|
pub async fn scan_transparent_accounts(
|
|
|
|
network: &Network,
|
|
|
|
client: &mut CompactTxStreamerClient<Channel>,
|
|
|
|
gap_limit: usize,
|
|
|
|
) -> anyhow::Result<()> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let c = CoinConfig::get_active();
|
2022-06-07 09:58:24 -07:00
|
|
|
let mut addresses = vec![];
|
2022-06-08 05:48:16 -07:00
|
|
|
let db = c.db()?;
|
|
|
|
let (seed, mut index) = db.get_seed(c.id_account)?;
|
2022-06-07 09:58:24 -07:00
|
|
|
if let Some(seed) = seed {
|
|
|
|
let mut gap = 0;
|
|
|
|
while gap < gap_limit {
|
|
|
|
let bip44_path = format!("m/44'/{}'/0'/0/{}", network.coin_type(), index);
|
|
|
|
log::info!("{} {}", index, bip44_path);
|
|
|
|
let (_, address) = derive_tkeys(network, &seed, &bip44_path)?;
|
|
|
|
let balance = get_taddr_balance(client, &address).await?;
|
|
|
|
if balance > 0 {
|
|
|
|
addresses.push(TBalance {
|
|
|
|
index,
|
|
|
|
address,
|
|
|
|
balance,
|
|
|
|
});
|
|
|
|
gap = 0;
|
|
|
|
} else {
|
|
|
|
gap += 1;
|
|
|
|
}
|
|
|
|
index += 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
db.store_t_scan(&addresses)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn derive_tkeys(
|
|
|
|
network: &Network,
|
|
|
|
phrase: &str,
|
|
|
|
path: &str,
|
|
|
|
) -> anyhow::Result<(String, String)> {
|
2022-06-08 05:48:16 -07:00
|
|
|
let mnemonic = Mnemonic::from_phrase(phrase, Language::English)?;
|
2021-07-09 06:33:05 -07:00
|
|
|
let seed = Seed::new(&mnemonic, "");
|
|
|
|
let secp = Secp256k1::<All>::new();
|
2022-06-08 05:48:16 -07:00
|
|
|
let ext = ExtendedPrivKey::derive(seed.as_bytes(), path).unwrap();
|
2021-07-09 06:33:05 -07:00
|
|
|
let secret_key = SecretKey::from_slice(&ext.secret()).unwrap();
|
|
|
|
let pub_key = PublicKey::from_secret_key(&secp, &secret_key);
|
|
|
|
let pub_key = pub_key.serialize();
|
|
|
|
let pub_key = Ripemd160::digest(&Sha256::digest(&pub_key));
|
|
|
|
let address = TransparentAddress::PublicKey(pub_key.into());
|
2021-07-16 01:42:29 -07:00
|
|
|
let address = encode_transparent_address(
|
2022-03-07 06:47:06 -08:00
|
|
|
&network.b58_pubkey_address_prefix(),
|
|
|
|
&network.b58_script_address_prefix(),
|
2021-07-16 01:42:29 -07:00
|
|
|
&address,
|
|
|
|
);
|
2022-05-19 09:19:04 -07:00
|
|
|
let sk = secret_key.display_secret().to_string();
|
2021-07-09 06:33:05 -07:00
|
|
|
Ok((sk, address))
|
|
|
|
}
|
2022-06-07 09:58:24 -07:00
|
|
|
|
|
|
|
pub struct TBalance {
|
|
|
|
pub index: u32,
|
|
|
|
pub address: String,
|
|
|
|
pub balance: u64,
|
|
|
|
}
|