use crate::config::ZingoConfig;
use pepper_sync::keys::transparent::{self, TransparentAddressId, TransparentScope};
use sapling_crypto::{
PaymentAddress,
zip32::{DiversifiableFullViewingKey, ExtendedSpendingKey},
};
use unified::{ReceiverSelection, UnifiedAddressId};
use zcash_keys::address::UnifiedAddress;
use zcash_primitives::{
consensus::NetworkConstants,
legacy::{TransparentAddress, keys::NonHardenedChildIndex},
zip32::ChildIndex,
};
use super::{LightWallet, error::KeyError};
pub mod legacy;
pub mod unified;
impl LightWallet {
pub fn generate_unified_address(
&mut self,
receivers: ReceiverSelection,
) -> Result<UnifiedAddress, KeyError> {
let unified_address_index = self
.unified_addresses
.keys()
.filter(|&address_id| address_id.account_id == zip32::AccountId::ZERO)
.count() as u32;
let unified_address = self.unified_key_store.generate_unified_address(
unified_address_index,
receivers,
false,
)?;
if let Some(transparent_address) = unified_address.transparent() {
self.transparent_addresses.insert(
TransparentAddressId::new(
zip32::AccountId::ZERO,
TransparentScope::External,
NonHardenedChildIndex::from_index(unified_address_index)
.expect("all non-hardened addresses in use!"),
),
transparent::encode_address(&self.network, *transparent_address),
);
}
self.unified_addresses.insert(
UnifiedAddressId {
account_id: zip32::AccountId::ZERO,
address_index: unified_address_index,
},
unified_address.clone(),
);
Ok(unified_address)
}
pub fn generate_refund_addresses(
&mut self,
n: usize,
) -> Result<Vec<(TransparentAddressId, TransparentAddress)>, KeyError> {
let refund_address_count = self
.transparent_addresses
.keys()
.filter(|&address_id| address_id.scope() == TransparentScope::Refund)
.count();
(refund_address_count..(refund_address_count + n))
.map(|address_index| {
let transparent_address_id = TransparentAddressId::new(
zip32::AccountId::ZERO,
TransparentScope::Refund,
NonHardenedChildIndex::from_index(address_index as u32)
.expect("all non-hardened addresses in use!"),
);
let refund_address = self.unified_key_store.generate_transparent_address(
address_index as u32,
TransparentScope::Refund,
false,
)?;
self.transparent_addresses.insert(
transparent_address_id,
transparent::encode_address(&self.network, refund_address),
);
Ok((transparent_address_id, refund_address))
})
.collect()
}
}
pub fn get_zaddr_from_bip39seed(
config: &ZingoConfig,
bip39_seed: &[u8],
pos: u32,
) -> (
ExtendedSpendingKey,
DiversifiableFullViewingKey,
PaymentAddress,
) {
assert_eq!(bip39_seed.len(), 64);
let extsk: ExtendedSpendingKey = ExtendedSpendingKey::from_path(
&ExtendedSpendingKey::master(bip39_seed),
&[
ChildIndex::hardened(32),
ChildIndex::hardened(config.chain.coin_type()),
ChildIndex::hardened(pos),
],
);
let fvk = extsk.to_diversifiable_full_viewing_key();
let address = fvk.default_address().1;
(extsk, fvk, address)
}