Skip to content

Commit

Permalink
Atomic version of derive_store_secret_key_from_mnemonic_code
Browse files Browse the repository at this point in the history
  • Loading branch information
karbyshev committed Mar 7, 2024
1 parent 7158ccd commit 47c98bd
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 45 deletions.
3 changes: 2 additions & 1 deletion crates/apps/src/lib/cli/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -479,7 +479,7 @@ async fn transparent_key_and_address_derive(
let encryption_password =
read_and_confirm_encryption_password(unsafe_dont_encrypt);
wallet
.derive_store_key_from_mnemonic_code(
.derive_store_secret_key_from_mnemonic_code(
scheme,
Some(alias),
alias_force,
Expand All @@ -488,6 +488,7 @@ async fn transparent_key_and_address_derive(
prompt_bip39_passphrase,
encryption_password,
)
.expect("Failed to update the wallet storage.")
.unwrap_or_else(|| {
edisplay_line!(io, "Failed to derive a keypair.");
display_line!(io, "No changes are persisted. Exiting.");
Expand Down
111 changes: 67 additions & 44 deletions crates/sdk/src/wallet/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -817,22 +817,16 @@ impl<U: WalletStorage> Wallet<U> {
}

impl<U: WalletIo> Wallet<U> {
/// Restore a spending key from the user mnemonic code (read from stdin)
/// using a given ZIP32 derivation path and insert it into the store with
/// the provided alias, converted to lower case.
/// The key is encrypted with the provided password. If no password
/// provided, will prompt for password from stdin.
/// Stores the key in decrypted key cache and returns the alias of the key
/// and a reference-counting pointer to the key.
pub fn derive_store_spending_key_from_mnemonic_code(
&mut self,
alias: String,
alias_force: bool,
/// XXX OK
/// Derive a keypair from the user mnemonic code (read from stdin) using
/// a given BIP44 derivation path.
pub fn derive_secret_key_from_mnemonic_code(
&self,
scheme: SchemeType,
derivation_path: DerivationPath,
mnemonic_passphrase: Option<(Mnemonic, Zeroizing<String>)>,
prompt_bip39_passphrase: bool,
password: Option<Zeroizing<String>>,
) -> Option<(String, ExtendedSpendingKey)> {
) -> Option<common::SecretKey> {
let (mnemonic, passphrase) =
if let Some(mnemonic_passphrase) = mnemonic_passphrase {
mnemonic_passphrase
Expand All @@ -846,39 +840,29 @@ impl<U: WalletIo> Wallet<U> {
(mnemonic, passphrase)
};
let seed = Seed::new(&mnemonic, &passphrase);
let spend_key =
derive_hd_spending_key(seed.as_bytes(), derivation_path.clone());

self.insert_spending_key(
alias,
alias_force,
spend_key,
password,
Some(derivation_path),
)
.map(|alias| (alias, spend_key))
Some(derive_hd_secret_key(
scheme,
seed.as_bytes(),
derivation_path.clone(),
))
}

/// Restore a keypair from the user mnemonic code (read from stdin) using
/// a given BIP44 derivation path and derive an implicit address from its
/// public part and insert them into the store with the provided alias,
/// converted to lower case. If none provided, the alias will be the public
/// key hash (in lowercase too).
/// Restore a spending key from the user mnemonic code (read from stdin)
/// using a given ZIP32 derivation path and insert it into the store with
/// the provided alias, converted to lower case.
/// The key is encrypted with the provided password. If no password
/// provided, will prompt for password from stdin.
/// Stores the key in decrypted key cache and returns the alias of the key
/// and a reference-counting pointer to the key.
#[allow(clippy::too_many_arguments)]
pub fn derive_store_key_from_mnemonic_code(
pub fn derive_store_spending_key_from_mnemonic_code(
&mut self,
scheme: SchemeType,
alias: Option<String>,
alias: String,
alias_force: bool,
derivation_path: DerivationPath,
mnemonic_passphrase: Option<(Mnemonic, Zeroizing<String>)>,
prompt_bip39_passphrase: bool,
password: Option<Zeroizing<String>>,
) -> Option<(String, common::SecretKey)> {
) -> Option<(String, ExtendedSpendingKey)> {
let (mnemonic, passphrase) =
if let Some(mnemonic_passphrase) = mnemonic_passphrase {
mnemonic_passphrase
Expand All @@ -892,21 +876,17 @@ impl<U: WalletIo> Wallet<U> {
(mnemonic, passphrase)
};
let seed = Seed::new(&mnemonic, &passphrase);
let sk = derive_hd_secret_key(
scheme,
seed.as_bytes(),
derivation_path.clone(),
);
let spend_key =
derive_hd_spending_key(seed.as_bytes(), derivation_path.clone());

self.insert_keypair(
alias.unwrap_or_default(),
self.insert_spending_key(
alias,
alias_force,
sk.clone(),
spend_key,
password,
None,
Some(derivation_path),
)
.map(|alias| (alias, sk))
.map(|alias| (alias, spend_key))
}

/// Generate a spending key similarly to how it's done for keypairs
Expand Down Expand Up @@ -1419,4 +1399,47 @@ impl<U: WalletIo + WalletStorage> Wallet<U> {
})?;
Ok(pay_addr_alias.map(Into::into))
}

// XXX OK
/// Derive a keypair from the user mnemonic code (read from stdin) using
/// a given BIP44 derivation path and derive an implicit address from its
/// public part and insert them into the store with the provided alias,
/// converted to lower case. If none provided, the alias will be the public
/// key hash (in lower case too).
/// The key is encrypted with the provided password. If no password
/// provided, will prompt for password from stdin.
/// Stores the key in decrypted key cache and returns the alias of the key
/// and the generated secret key.
#[allow(clippy::too_many_arguments)]
pub fn derive_store_secret_key_from_mnemonic_code(
&mut self,
scheme: SchemeType,
alias: Option<String>,
alias_force: bool,
derivation_path: DerivationPath,
mnemonic_passphrase: Option<(Mnemonic, Zeroizing<String>)>,
prompt_bip39_passphrase: bool,
password: Option<Zeroizing<String>>,
) -> Result<Option<(String, common::SecretKey)>, LoadStoreError> {
self.derive_secret_key_from_mnemonic_code(
scheme,
derivation_path.clone(),
mnemonic_passphrase,
prompt_bip39_passphrase,
)
.map(|sk| {
self.insert_keypair_atomic(
alias.unwrap_or_default(),
alias_force,
sk.clone(),
password,
None,
Some(derivation_path),
)
.map(|o| o.map(|alias| (alias, sk)))
.transpose()
})
.flatten()
.transpose()
}
}

0 comments on commit 47c98bd

Please sign in to comment.