docs: add example for mnemonic (#258)
* cleanup: use helper secret_to_address function from ethers-core * docs: add example for mnemonic
This commit is contained in:
parent
79862ffda5
commit
2640757d8a
|
@ -1,10 +1,14 @@
|
|||
//! Specific helper functions for creating/loading a mnemonic private key following BIP-39
|
||||
//! specifications
|
||||
use crate::{wallet::util::key_to_address, Wallet, WalletError};
|
||||
use crate::{Wallet, WalletError};
|
||||
|
||||
use coins_bip32::path::DerivationPath;
|
||||
use coins_bip39::{Mnemonic, Wordlist};
|
||||
use ethers_core::{k256::ecdsa::SigningKey, types::PathOrString, utils::to_checksum};
|
||||
use ethers_core::{
|
||||
k256::ecdsa::SigningKey,
|
||||
types::PathOrString,
|
||||
utils::{secret_key_to_address, to_checksum},
|
||||
};
|
||||
use rand::Rng;
|
||||
use std::{fs::File, io::Write, marker::PhantomData, path::PathBuf, str::FromStr};
|
||||
use thiserror::Error;
|
||||
|
@ -174,7 +178,7 @@ impl<W: Wordlist> MnemonicBuilder<W> {
|
|||
mnemonic.derive_key(&self.derivation_path, self.password.as_deref())?;
|
||||
let key: &SigningKey = derived_priv_key.as_ref();
|
||||
let signer = SigningKey::from_bytes(&key.to_bytes())?;
|
||||
let address = key_to_address(&signer);
|
||||
let address = secret_key_to_address(&signer);
|
||||
|
||||
Ok(Wallet::<SigningKey> {
|
||||
signer,
|
||||
|
|
|
@ -6,8 +6,6 @@ pub use mnemonic::{MnemonicBuilder, MnemonicBuilderError};
|
|||
mod private_key;
|
||||
pub use private_key::WalletError;
|
||||
|
||||
mod util;
|
||||
|
||||
#[cfg(feature = "yubihsm")]
|
||||
mod yubi;
|
||||
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
//! Specific helper functions for loading an offline K256 Private Key stored on disk
|
||||
use super::Wallet;
|
||||
|
||||
use crate::wallet::{mnemonic::MnemonicBuilderError, util::key_to_address};
|
||||
use crate::wallet::mnemonic::MnemonicBuilderError;
|
||||
use coins_bip32::Bip32Error;
|
||||
use coins_bip39::MnemonicError;
|
||||
use eth_keystore::KeystoreError;
|
||||
use ethers_core::{
|
||||
k256::ecdsa::{self, SigningKey},
|
||||
rand::{CryptoRng, Rng},
|
||||
utils::secret_key_to_address,
|
||||
};
|
||||
use std::{path::Path, str::FromStr};
|
||||
use thiserror::Error;
|
||||
|
@ -60,7 +61,7 @@ impl Wallet<SigningKey> {
|
|||
{
|
||||
let (secret, _) = eth_keystore::new(dir, rng, password)?;
|
||||
let signer = SigningKey::from_bytes(secret.as_slice())?;
|
||||
let address = key_to_address(&signer);
|
||||
let address = secret_key_to_address(&signer);
|
||||
Ok(Self {
|
||||
signer,
|
||||
address,
|
||||
|
@ -76,7 +77,7 @@ impl Wallet<SigningKey> {
|
|||
{
|
||||
let secret = eth_keystore::decrypt_key(keypath, password)?;
|
||||
let signer = SigningKey::from_bytes(secret.as_slice())?;
|
||||
let address = key_to_address(&signer);
|
||||
let address = secret_key_to_address(&signer);
|
||||
Ok(Self {
|
||||
signer,
|
||||
address,
|
||||
|
@ -87,7 +88,7 @@ impl Wallet<SigningKey> {
|
|||
/// Creates a new random keypair seeded with the provided RNG
|
||||
pub fn new<R: Rng + CryptoRng>(rng: &mut R) -> Self {
|
||||
let signer = SigningKey::random(rng);
|
||||
let address = key_to_address(&signer);
|
||||
let address = secret_key_to_address(&signer);
|
||||
Self {
|
||||
signer,
|
||||
address,
|
||||
|
@ -106,7 +107,7 @@ impl PartialEq for Wallet<SigningKey> {
|
|||
|
||||
impl From<SigningKey> for Wallet<SigningKey> {
|
||||
fn from(signer: SigningKey) -> Self {
|
||||
let address = key_to_address(&signer);
|
||||
let address = secret_key_to_address(&signer);
|
||||
|
||||
Self {
|
||||
signer,
|
||||
|
@ -122,7 +123,7 @@ impl From<K256SecretKey> for Wallet<SigningKey> {
|
|||
fn from(key: K256SecretKey) -> Self {
|
||||
let signer = SigningKey::from_bytes(&*key.to_bytes())
|
||||
.expect("private key should always be convertible to signing key");
|
||||
let address = key_to_address(&signer);
|
||||
let address = secret_key_to_address(&signer);
|
||||
|
||||
Self {
|
||||
signer,
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
use ethers_core::{
|
||||
k256::{ecdsa::SigningKey, EncodedPoint as K256PublicKey},
|
||||
types::Address,
|
||||
utils::keccak256,
|
||||
};
|
||||
|
||||
pub fn key_to_address(secret_key: &SigningKey) -> Address {
|
||||
// TODO: Can we do this in a better way?
|
||||
let uncompressed_pub_key = K256PublicKey::from(&secret_key.verify_key()).decompress();
|
||||
let public_key = uncompressed_pub_key.unwrap().to_bytes();
|
||||
debug_assert_eq!(public_key[0], 0x04);
|
||||
let hash = keccak256(&public_key[1..]);
|
||||
Address::from_slice(&hash[12..])
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
use ethers::signers::{coins_bip39::English, MnemonicBuilder};
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
let phrase = "work man father plunge mystery proud hollow address reunion sauce theory bonus";
|
||||
let index = 0u32;
|
||||
let password = "TREZOR123";
|
||||
|
||||
// Access mnemonic phrase with password
|
||||
// Child key at derivation path: m/44'/60'/0'/0/{index}
|
||||
let wallet = MnemonicBuilder::<English>::default()
|
||||
.phrase(phrase)
|
||||
.index(index)?
|
||||
// Use this if your mnemonic is encrypted
|
||||
.password(password)
|
||||
.build()?;
|
||||
|
||||
dbg!(&wallet);
|
||||
|
||||
// Generate a random wallet (24 word phrase) at custom derivation path
|
||||
let mut rng = rand::thread_rng();
|
||||
let wallet = MnemonicBuilder::<English>::default()
|
||||
.word_count(24)
|
||||
.derivation_path("m/44'/60'/0'/2/1")?
|
||||
// Optionally add this if you want the generated mnemonic to be written
|
||||
// to a file
|
||||
// .write_to(path)
|
||||
.build_random(&mut rng)?;
|
||||
|
||||
dbg!(&wallet);
|
||||
|
||||
Ok(())
|
||||
}
|
Loading…
Reference in New Issue