Skip to content

Commit

Permalink
transparent: Add Bip32Derivation::extract_bip_44_fields
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Dec 18, 2024
1 parent 285d4b8 commit 4b3d2bb
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 1 deletion.
3 changes: 3 additions & 0 deletions zcash_transparent/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ and this library adheres to Rust's notion of
- `zcash_transparent::keys::AccountPubKey::derive_pubkey_at_bip32_path` now
returns the correct result for valid paths instead of an error or panic.

### Added
- `zcash_transparent::pczt::Bip32Derivation::extract_bip_44_fields`

## [0.1.0] - 2024-12-16

The entries below are relative to the `zcash_primitives` crate as of the tag
Expand Down
46 changes: 45 additions & 1 deletion zcash_transparent/src/pczt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ use bip32::ChildNumber;
use getset::Getters;
use zcash_protocol::{value::Zatoshis, TxId};

use crate::{address::Script, sighash::SighashType};
use crate::{
address::Script,
keys::{NonHardenedChildIndex, TransparentKeyScope},
sighash::SighashType,
};

mod parse;
pub use parse::ParseError;
Expand Down Expand Up @@ -230,3 +234,43 @@ pub struct Bip32Derivation {
/// The sequence of indices corresponding to the HD path.
derivation_path: Vec<ChildNumber>,
}

impl Bip32Derivation {
/// Extracts the BIP 44 account index, scope, and address 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_bip_44_fields(
&self,
seed_fp: &zip32::fingerprint::SeedFingerprint,
expected_coin_type: ChildNumber,
) -> Option<(zip32::AccountId, TransparentKeyScope, NonHardenedChildIndex)> {
if self.seed_fingerprint == seed_fp.to_bytes() {
match &self.derivation_path[..] {
[purpose, coin_type, account_index, scope, address_index]
if purpose == &ChildNumber(44 | ChildNumber::HARDENED_FLAG)
&& coin_type.is_hardened()
&& coin_type == &expected_coin_type
&& account_index.is_hardened()
&& !scope.is_hardened()
&& !address_index.is_hardened() =>
{
let account_index = zip32::AccountId::try_from(account_index.index())
.expect("account_index is hardened");

let scope =
TransparentKeyScope::custom(scope.index()).expect("scope is not hardened");

let address_index = NonHardenedChildIndex::from_index(address_index.index())
.expect("address_index is not hardened");

Some((account_index, scope, address_index))
}
_ => None,
}
} else {
None
}
}
}

0 comments on commit 4b3d2bb

Please sign in to comment.