zcash-sync/src/ledger/account.rs

52 lines
2.2 KiB
Rust

use anyhow::Result;
use rusqlite::{params, Connection, OptionalExtension};
use zcash_client_backend::encoding::{encode_payment_address, encode_extended_full_viewing_key};
use zcash_primitives::{consensus::Parameters, zip32::ExtendedFullViewingKey};
use crate::{db::read::get_account_by_address, taddr::derive_from_pubkey, CoinConfig};
use super::transport::*;
pub async fn import(coin: u8, name: &str) -> Result<u32> {
let c = CoinConfig::get(coin);
let network = c.chain.network();
ledger_init().await?;
let dfvk = ledger_get_dfvk().await?;
let fvk = ExtendedFullViewingKey::from_diversifiable_full_viewing_key(&dfvk);
let fvk = encode_extended_full_viewing_key(network.hrp_sapling_extended_full_viewing_key(), &fvk);
let (_, pa) = dfvk.default_address();
let address = encode_payment_address(network.hrp_sapling_payment_address(), &pa);
let mut db = c.db()?;
if let Some(account) = get_account_by_address(&db.connection, &address)? {
return Ok(account)
}
let pub_key = ledger_get_pubkey().await?;
let t_address = derive_from_pubkey(network, &pub_key)?;
println!("OFVK");
let o_fvk = ledger_get_o_fvk().await?;
println!("fvk {}", hex::encode(&o_fvk));
println!("OFVK2");
let db_transaction = db.begin_transaction()?;
db_transaction.execute("INSERT INTO accounts(name, seed, aindex, sk, ivk, address) VALUES
(?1, NULL, 0, NULL, ?2, ?3)", params![name, fvk, address])?;
let id_account = db_transaction.last_insert_rowid() as u32;
db_transaction.execute("INSERT INTO taddrs(account, sk, address) VALUES
(?1, NULL, ?2)", params![id_account, t_address])?;
db_transaction.execute("INSERT INTO orchard_addrs(account, sk, fvk) VALUES
(?1, NULL, ?2)", params![id_account, o_fvk])?;
db_transaction.execute("INSERT INTO hw_wallets(account, ledger) VALUES
(?1, 1)", [id_account])?;
db_transaction.commit()?;
Ok(id_account)
}
pub fn is_external(connection: &Connection, account: u32) -> Result<bool> {
let res = connection.query_row("SELECT ledger FROM hw_wallets WHERE account = ?1", [account], |row| {
row.get::<_, bool>(0)
}).optional()?;
Ok(res.unwrap_or(false))
}