1

I tried to implement the example from the cookbook, but I made a mistake somewhere. Or I misunderstood something https://solanacookbook.com/references/keypairs-and-wallets.html#how-to-restore-a-keypair-from-a-mnemonic-phrase

[dependencies]
bip39 = { version = "2.0.0", features = ["rand"] }
derivation-path = "0.2.0"
hdpath = "0.6.3"
slip10 = "0.4.3"
solana-sdk = { version = "2.0.8", features = ["curve25519-dalek"] }
tiny-hderive = "0.3.0"

main.rs

use bip39::{Language, Mnemonic};
// use derivation_path::{ChildIndex, DerivationPath};
use solana_sdk::derivation_path::DerivationPath;
use solana_sdk::signature::SeedDerivable;
use solana_sdk::signature::{Keypair, Signer};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mnemonic = "neither lonely flavor argue grass remind eye tag avocado spot unusual intact";
    let mnemonic = Mnemonic::parse_in_normalized(Language::English, mnemonic)?;
    let seed = mnemonic.to_seed("");

    for i in 0..10 {
        let path = format!("m/44'/501'/{}'/0'", i);
        println!("{}", path);
        let der_path = DerivationPath::try_from(path.as_str()).unwrap();

        // let master = ExtendedPrivKey::derive(&seed, der_path).unwrap();
        // let derived = master.derive(&path);
        // let secret = SecretKey::from_bytes(&derived.secret())?;
        let keypair = Keypair::from_seed_and_derivation_path(&seed, Some(der_path)).unwrap();
        // let keypair = Keypair::from_bytes(&master)?;
        let pubkey = keypair.pubkey();

        println!("{} => {}", path, pubkey);
    }

    Ok(())
}

1 Answer 1

1

The best practice for readers to be able to help is to provide the error that is thrown by the code.

With this, I believe it will be

called `Result::unwrap()` on an `Err` value: InvalidDerivationPath("invalid child index: could not parse child index: invalid digit found in string")

When expecting to get a Rust stack trace of the error with export RUST_BACKTRACE=full we can see the error is thrown from the try_from call at Solana SDK https://github.com/anza-xyz/agave/blob/v2.0.9/sdk/src/derivation_path.rs#L53

That method calls into https://github.com/anza-xyz/agave/blob/v2.0.9/sdk/src/derivation_path.rs#L69

where the API expects the coin (https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki#path-levels) to be provided explicitly being Solana. The solution could be to strip the path from m'/44'/501/' or switch to method DerivationPath::from_absolute_path_str.

with the use of

let path = format!("{}'/0'", i);
let derivation_path = DerivationPath::try_from(path.as_str()).unwrap();

the code seems to be working well

0'/0' => 5vftMkHL72JaJG6ExQfGAsT2uGVHpRR7oTNUPMs68Y2N
1'/0' => GcXbfQ5yY3uxCyBNDPBbR5FjumHf89E7YHXuULfGDBBv
2'/0' => 7QPgyQwNLqnoSwHEuK8wKy2Y3Ani6EHoZRihTuWkwxbc
3'/0' => 5aE8UprEEWtpVskhxo3f8ETco2kVKiZT9SS3D5Lcg8s2
4'/0' => 5n6afo6LZmzH1J4R38ZCaNSwaztLjd48nWwToLQkCHxp
5'/0' => 2Gr1hWnbaqGXMghicSTHncqV7GVLLddNFJDC7YJoso8M
6'/0' => BNMDY3tCyYbayMzBjZm8RW59unpDWcQRfVmWXCJhLb7D
7'/0' => 9CySTpi4iC85gMW6G4BMoYbNBsdyJrfseHoGmViLha63
8'/0' => ApteF7PmUWS8Lzm6tJPkWgrxSFW5LwYGWCUJ2ByAec91
9'/0' => 6frdqXQAgJMyKwmZxkLYbdGjnYTvUceh6LNhkQt2siQp

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.