Import t-addr by derivation path

This commit is contained in:
Hanh 2022-07-17 11:23:56 +08:00
parent c72c69d0b5
commit 33d34cbc9e
6 changed files with 56 additions and 19 deletions

View File

@ -39,7 +39,9 @@ void reset_app(void);
uint32_t new_account(uint8_t coin, char *name, char *data, int32_t index);
uint32_t new_sub_account(char *name, int32_t index, uint32_t count);
void new_sub_account(char *name, int32_t index, uint32_t count);
void import_transparent_key(uint8_t coin, uint32_t id_account, char *path);
uint8_t warp(uint8_t coin, bool get_tx, uint32_t anchor_offset, int64_t port);

View File

@ -2,6 +2,7 @@
use crate::coinconfig::CoinConfig;
use crate::key2::decode_key;
use crate::taddr::derive_tkeys;
use anyhow::anyhow;
use bip39::{Language, Mnemonic};
use rand::rngs::OsRng;
@ -53,6 +54,16 @@ fn new_account_with_key(coin: u8, name: &str, key: &str, index: u32) -> anyhow::
Ok(account)
}
pub fn import_transparent_key(coin: u8, id_account: u32, path: &str) -> anyhow::Result<()> {
let c = CoinConfig::get(coin);
let db = c.db()?;
let (seed, _) = db.get_seed(c.id_account)?;
let seed = seed.ok_or_else(|| anyhow!("Account has no seed"))?;
let (sk, addr) = derive_tkeys(c.chain.network(), &seed, path)?;
db.store_transparent_key(id_account, &sk, &addr)?;
Ok(())
}
pub fn new_diversified_address() -> anyhow::Result<String> {
let c = CoinConfig::get_active();
let db = c.db()?;

View File

@ -169,6 +169,13 @@ pub unsafe extern "C" fn new_sub_account(name: *mut c_char, index: i32, count: u
log_result(res)
}
#[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);
log_result(res)
}
lazy_static! {
static ref SYNC_LOCK: Semaphore = Semaphore::new(1);
}

View File

@ -141,6 +141,19 @@ impl DbAdapter {
Ok(index as u32)
}
pub fn store_transparent_key(
&self,
id_account: u32,
sk: &str,
addr: &str,
) -> anyhow::Result<()> {
self.connection.execute(
"UPDATE taddrs SET sk = ?1, address = ?2 WHERE account = ?3",
params![sk, addr, id_account],
)?;
Ok(())
}
pub fn get_fvks(&self) -> anyhow::Result<HashMap<u32, AccountViewKey>> {
let mut statement = self
.connection

View File

@ -308,28 +308,30 @@ pub async fn sync_async(
}
log::info!("Transaction Details : {}", start.elapsed().as_millis());
log::info!("progress: {}", blocks.0[0].height);
let callback = proc_callback.lock().await;
callback(blocks.0[0].height as u32);
let (new_tree, new_witnesses) = bp.finalize();
tree = new_tree;
witnesses = new_witnesses;
if let Some(block) = blocks.0.last() {
let mut db_transaction = db.begin_transaction()?;
let height = block.height as u32;
for w in witnesses.iter() {
DbAdapter::store_witnesses(&db_transaction, w, height, w.id_note)?;
{
let mut db_transaction = db.begin_transaction()?;
let height = block.height as u32;
for w in witnesses.iter() {
DbAdapter::store_witnesses(&db_transaction, w, height, w.id_note)?;
}
DbAdapter::store_block(
&mut db_transaction,
height,
&block.hash,
block.time,
&tree,
)?;
db_transaction.commit()?;
// db_transaction is dropped here
}
DbAdapter::store_block(
&mut db_transaction,
height,
&block.hash,
block.time,
&tree,
)?;
db_transaction.commit()?;
log::info!("progress: {}", block.height);
let callback = proc_callback.lock().await;
callback(block.height as u32);
}
}

View File

@ -1,5 +1,6 @@
use crate::coinconfig::CoinConfig;
use crate::{AddressList, CompactTxStreamerClient, GetAddressUtxosArg, GetAddressUtxosReply};
use anyhow::anyhow;
use bip39::{Language, Mnemonic, Seed};
use ripemd::{Digest, Ripemd160};
use secp256k1::{All, PublicKey, Secp256k1, SecretKey};
@ -83,8 +84,9 @@ pub fn derive_tkeys(
let mnemonic = Mnemonic::from_phrase(phrase, Language::English)?;
let seed = Seed::new(&mnemonic, "");
let secp = Secp256k1::<All>::new();
let ext = ExtendedPrivKey::derive(seed.as_bytes(), path).unwrap();
let secret_key = SecretKey::from_slice(&ext.secret()).unwrap();
let ext = ExtendedPrivKey::derive(seed.as_bytes(), path)
.map_err(|_| anyhow!("Invalid derivation path"))?;
let secret_key = SecretKey::from_slice(&ext.secret())?;
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));