From 7c05fcbce35fa6b363612f1b6114ebed17881c8f Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Fri, 30 Aug 2024 14:30:16 -0600 Subject: [PATCH] Add unstable `UnifiedFullViewingKey::from_sapling_extended_full_viewing_key` --- zcash_keys/CHANGELOG.md | 2 ++ zcash_keys/src/encoding.rs | 10 ++++++++++ zcash_keys/src/keys.rs | 23 +++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/zcash_keys/CHANGELOG.md b/zcash_keys/CHANGELOG.md index e7454fb178..df5dc795e3 100644 --- a/zcash_keys/CHANGELOG.md +++ b/zcash_keys/CHANGELOG.md @@ -8,6 +8,8 @@ and this library adheres to Rust's notion of ### Added - `zcash_keys::encoding::decode_extfvk_with_network` +- `impl std::error::Error for DecodingError` +- `impl std::error::Error for Bech32DecodeError` ## [0.3.0] - 2024-08-19 ### Notable changes diff --git a/zcash_keys/src/encoding.rs b/zcash_keys/src/encoding.rs index f53931f7da..894103a04b 100644 --- a/zcash_keys/src/encoding.rs +++ b/zcash_keys/src/encoding.rs @@ -66,6 +66,16 @@ impl fmt::Display for Bech32DecodeError { } } +#[cfg(feature = "sapling")] +impl std::error::Error for Bech32DecodeError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match &self { + Bech32DecodeError::Bech32Error(e) => Some(e), + _ => None, + } + } +} + #[cfg(feature = "sapling")] fn bech32_decode(hrp: &str, s: &str, read: F) -> Result where diff --git a/zcash_keys/src/keys.rs b/zcash_keys/src/keys.rs index f1f8d6eb6c..86f0587459 100644 --- a/zcash_keys/src/keys.rs +++ b/zcash_keys/src/keys.rs @@ -37,6 +37,9 @@ use { #[cfg(feature = "orchard")] use orchard::{self, keys::Scope}; +#[cfg(all(feature = "sapling", feature = "unstable"))] +use ::sapling::zip32::ExtendedFullViewingKey; + #[cfg(feature = "sapling")] pub mod sapling { pub use sapling::zip32::{ @@ -176,6 +179,8 @@ impl std::fmt::Display for DecodingError { } } +impl std::error::Error for DecodingError {} + #[cfg(feature = "unstable")] impl Era { /// Returns the unique identifier for the era. @@ -674,6 +679,24 @@ impl UnifiedFullViewingKey { vec![], ) } + + #[cfg(all(feature = "sapling", feature = "unstable"))] + pub fn from_sapling_extended_full_viewing_key( + sapling: ExtendedFullViewingKey, + ) -> Result { + Self::from_checked_parts( + #[cfg(feature = "transparent-inputs")] + None, + #[cfg(feature = "sapling")] + Some(sapling.to_diversifiable_full_viewing_key()), + #[cfg(feature = "orchard")] + None, + // We don't currently allow constructing new UFVKs with unknown items, but we store + // this to allow parsing such UFVKs. + vec![], + ) + } + /// Construct a UFVK from its constituent parts, after verifying that UIVK derivation can /// succeed. fn from_checked_parts(