solana_keypair/
seed_derivable.rs

1//! Implementation of the SeedDerivable trait for Keypair
2
3use {
4    crate::{keypair_from_seed, keypair_from_seed_phrase_and_passphrase, Keypair},
5    ed25519_dalek_bip32::Error as Bip32Error,
6    solana_derivation_path::DerivationPath,
7    solana_seed_derivable::SeedDerivable,
8    std::error,
9};
10
11impl SeedDerivable for Keypair {
12    fn from_seed(seed: &[u8]) -> Result<Self, Box<dyn error::Error>> {
13        keypair_from_seed(seed)
14    }
15
16    fn from_seed_and_derivation_path(
17        seed: &[u8],
18        derivation_path: Option<DerivationPath>,
19    ) -> Result<Self, Box<dyn error::Error>> {
20        keypair_from_seed_and_derivation_path(seed, derivation_path)
21    }
22
23    fn from_seed_phrase_and_passphrase(
24        seed_phrase: &str,
25        passphrase: &str,
26    ) -> Result<Self, Box<dyn error::Error>> {
27        keypair_from_seed_phrase_and_passphrase(seed_phrase, passphrase)
28    }
29}
30
31/// Generates a Keypair using Bip32 Hierarchical Derivation if derivation-path is provided;
32/// otherwise generates the base Bip44 Solana keypair from the seed
33pub fn keypair_from_seed_and_derivation_path(
34    seed: &[u8],
35    derivation_path: Option<DerivationPath>,
36) -> Result<Keypair, Box<dyn error::Error>> {
37    let derivation_path = derivation_path.unwrap_or_default();
38    bip32_derived_keypair(seed, derivation_path).map_err(|err| err.to_string().into())
39}
40
41/// Generates a Keypair using Bip32 Hierarchical Derivation
42fn bip32_derived_keypair(
43    seed: &[u8],
44    derivation_path: DerivationPath,
45) -> Result<Keypair, Bip32Error> {
46    let extended = ed25519_dalek_bip32::ExtendedSecretKey::from_seed(seed)
47        .and_then(|extended| extended.derive(&derivation_path))?;
48    let extended_public_key = extended.public_key();
49    Ok(Keypair::from(ed25519_dalek::Keypair {
50        secret: extended.secret_key,
51        public: extended_public_key,
52    }))
53}