Skip to content

Commit

Permalink
Merge pull request #359 from zancas/viewkey_export
Browse files Browse the repository at this point in the history
Viewkey export
  • Loading branch information
zancas authored May 31, 2023
2 parents b3c0bb1 + 63b4634 commit 4112caf
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 13 deletions.
53 changes: 40 additions & 13 deletions zingolib/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,27 @@ impl Command for ChangeServerCommand {
}
}

struct GetBirthdayCommand {}
impl Command for GetBirthdayCommand {
fn help(&self) -> &'static str {
indoc! {r#"
Introspect over wallet value transfers, and report the lowest observed block height.
Usage:
get_birthday
Example:
get_birthday
"#}
}

fn short_help(&self) -> &'static str {
"Get wallet birthday."
}

fn exec(&self, _args: &[&str], lightclient: &LightClient) -> String {
RT.block_on(async move { lightclient.do_get_birthday().await.to_string() })
}
}
struct InterruptCommand {}
impl Command for InterruptCommand {
fn help(&self) -> &'static str {
Expand Down Expand Up @@ -459,29 +480,34 @@ impl Command for AddressCommand {
}
}

struct ExportCommand {}
impl Command for ExportCommand {
struct ExportUfvkCommand {}
impl Command for ExportUfvkCommand {
fn help(&self) -> &'static str {
indoc! {r#"
Export private key for an individual wallet addresses.
Note: To backup the whole wallet, use the 'seed' command insted
Export Unified full viewing key for the wallet.
Note: If you want to backup spend capability, use the 'seed' command insted
Usage:
export [t-address or z-address]
If no address is passed, private key for all addresses in the wallet are exported.
exportufvk
Example:
export ztestsapling1x65nq4dgp0qfywgxcwk9n0fvm4fysmapgr2q00p85ju252h6l7mmxu2jg9cqqhtvzd69jwhgv8d
exportufvk
"#}
}

fn short_help(&self) -> &'static str {
"Export private key for wallet addresses"
}

fn exec(&self, _args: &[&str], _lightclient: &LightClient) -> String {
"Key export currently unimplemented, please use seed phrase to backup/restore keys"
.to_string()
fn exec(&self, _args: &[&str], lightclient: &LightClient) -> String {
let key = RT.block_on(lightclient.wallet.transaction_context.key.read());
let ufvk_res = key.ufvk();
match ufvk_res {
Ok(ufvk) => {
use zcash_address::unified::Encoding as _;
ufvk.encode(&lightclient.config().chain.to_zcash_address_network())
}
Err(e) => format!("Error: {e}"),
}
}
}

Expand Down Expand Up @@ -1274,7 +1300,7 @@ impl Command for QuitCommand {
}

pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> {
let entries: [(&'static str, Box<dyn Command>); 32] = [
let entries: [(&'static str, Box<dyn Command>); 33] = [
("sync", Box::new(SyncCommand {})),
("syncstatus", Box::new(SyncStatusCommand {})),
("encryptmessage", Box::new(EncryptMessageCommand {})),
Expand All @@ -1295,7 +1321,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> {
("sends_to_address", Box::new(SendsToAddressCommand {})),
("getoption", Box::new(GetOptionCommand {})),
("import", Box::new(ImportCommand {})),
("export", Box::new(ExportCommand {})),
("exportufvk", Box::new(ExportUfvkCommand {})),
("info", Box::new(InfoCommand {})),
("updatecurrentprice", Box::new(UpdateCurrentPriceCommand {})),
("send", Box::new(SendCommand {})),
Expand All @@ -1307,6 +1333,7 @@ pub fn get_commands() -> HashMap<&'static str, Box<dyn Command>> {
("new", Box::new(NewAddressCommand {})),
("defaultfee", Box::new(DefaultFeeCommand {})),
("seed", Box::new(SeedCommand {})),
("get_birthday", Box::new(GetBirthdayCommand {})),
];

HashMap::from(entries)
Expand Down
10 changes: 10 additions & 0 deletions zingolib/src/lightclient.rs
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,16 @@ impl LightClient {
finsight::ValuesSentToAddress(amount_by_address)
}

pub async fn do_get_birthday(&self) -> u64 {
let summaries = self.do_list_txsummaries().await;
let mut min_height = 0;
for summary in summaries {
if u64::from(summary.block_height) < min_height {
min_height = u64::from(summary.block_height);
}
}
min_height
}
pub async fn do_total_value_to_address(&self) -> finsight::TotalValueToAddress {
let values_sent_to_addresses = self.value_transfer_by_to_address().await;
let mut by_address_total = HashMap::new();
Expand Down
20 changes: 20 additions & 0 deletions zingolib/src/wallet/keys/unified.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,26 @@ impl WalletCapability {
}
}

pub(crate) fn ufvk(&self) -> Result<Ufvk, zcash_address::unified::ParseError> {
let o_fvk = Fvk::Orchard(
orchard::keys::FullViewingKey::try_from(self)
.unwrap()
.to_bytes(),
);
let s_fvk = Fvk::Sapling(
zcash_primitives::zip32::sapling::DiversifiableFullViewingKey::try_from(self)
.unwrap()
.to_bytes(),
);
let mut t_fvk_bytes = [0u8; 65];
let t_ext_pk: ExtendedPubKey = self.try_into().unwrap();
t_fvk_bytes[0..32].copy_from_slice(&t_ext_pk.chain_code[..]);
t_fvk_bytes[32..65].copy_from_slice(&t_ext_pk.public_key.serialize()[..]);
let t_fvk = Fvk::P2pkh(t_fvk_bytes);
use zcash_address::unified::Encoding as _;
Ufvk::try_from_items(vec![o_fvk, s_fvk, t_fvk])
}

pub fn new_address(
&mut self,
desired_receivers: ReceiverSelection,
Expand Down

0 comments on commit 4112caf

Please sign in to comment.