diff --git a/CHANGELOG.md b/CHANGELOG.md index 9210dab16..36e4da4b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ and this project adheres to Rust's notion of ## [Unreleased] +### Added +- `orchard::pczt::Zip32Derivation::extract_account_index` + ### Changed - Migrated to `nonempty 0.11`. diff --git a/src/pczt.rs b/src/pczt.rs index 38cc0a757..4381c7c3e 100644 --- a/src/pczt.rs +++ b/src/pczt.rs @@ -301,6 +301,35 @@ pub struct Zip32Derivation { derivation_path: Vec, } +impl Zip32Derivation { + /// Extracts the ZIP 32 account index from this derivation path. + /// + /// Returns `None` if the seed fingerprints don't match, or if this is a non-standard + /// derivation path. + pub fn extract_account_index( + &self, + seed_fp: &zip32::fingerprint::SeedFingerprint, + expected_coin_type: zip32::ChildIndex, + ) -> Option { + if self.seed_fingerprint == seed_fp.to_bytes() { + match &self.derivation_path[..] { + [purpose, coin_type, account_index] + if purpose == &zip32::ChildIndex::hardened(32) + && coin_type == &expected_coin_type => + { + Some( + zip32::AccountId::try_from(account_index.index() - (1 << 31)) + .expect("zip32::ChildIndex only supports hardened"), + ) + } + _ => None, + } + } else { + None + } + } +} + #[cfg(test)] mod tests { use bridgetree::BridgeTree;