use super::*;
pub struct Public {
state: Box<dyn State<PublicState>>,
account: Bip44PublicAccount<Secp256k1>,
vault_dirty: Box<dyn State<bool>>,
}
impl PluginPublic<Plugin> for Public {
fn create(plugin: &Plugin, vault_dirty: Box<dyn State<bool>>) -> Result<Self> {
let network = plugin.network();
let account = plugin.account();
let state = plugin.to_state();
let xpub = {
let tmp = state.try_borrow()?;
tmp.xpub.to_owned()
};
let account = Bip44PublicAccount::<Secp256k1>::from_xpub(account, &xpub, network)?;
Ok(Self { state, account, vault_dirty })
}
}
impl Public {
pub fn node(&self) -> &Bip32PublicNode<Secp256k1> {
self.account.node()
}
pub fn bip44_path(&self) -> &Bip44AccountPath {
self.account.bip44_path()
}
pub fn network(&self) -> &'static dyn Network<Suite = Secp256k1> {
self.account.network()
}
pub fn key(&self, idx: i32) -> Result<Bip44PublicKey<Secp256k1>> {
ensure_idx_bounds(self.state.as_ref(), idx)?;
self.account.key(idx)
}
pub fn key_mut(&mut self, idx: i32) -> Result<Bip44PublicKey<Secp256k1>> {
touch_receive_idx(self.state.as_mut(), idx, self.vault_dirty.as_mut())?;
self.account.key(idx)
}
pub fn key_by_p2pkh_addr(&self, addr: &str) -> Result<Bip44PublicKey<Secp256k1>> {
let receive_keys = self.receive_keys()?;
for idx in 0..receive_keys {
let key = self.account.key(idx as i32)?;
if key.to_p2pkh_addr() == *addr {
return Ok(key);
}
}
bail!("Could not find {} among Hydra keys", addr)
}
pub fn xpub(&self) -> Result<String> {
let state = self.state.try_borrow()?;
Ok(state.xpub.to_owned())
}
pub fn receive_keys(&self) -> Result<u32> {
let state = self.state.try_borrow()?;
Ok(state.receive_keys)
}
pub fn change_keys(&self) -> Result<u32> {
let state = self.state.try_borrow()?;
Ok(state.change_keys)
}
pub(super) fn new(
state: Box<dyn State<PublicState>>, account: Bip44PublicAccount<Secp256k1>,
vault_dirty: Box<dyn State<bool>>,
) -> Self {
Self { state, account, vault_dirty }
}
}