-
-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
--restore-wallet restores words from file #295
--restore-wallet restores words from file #295
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
light review, I should checkout the branch! but in the meanwhile I left some comments
There is some problem with the wallet design as of now. If there is a wallet that already exists in the |
I played with the code, what is wrong with my solution? @Psycho-Pirate It solved some problems and removed the mnemonic as a However, I am open to discussing if there is any case that I am not keeping into count? Probably this is also the problem that @Harshit933 point out inside the review P.S: At this stage of lampo we should refactor the code and make it better, and not try to work with the current codebase, because most of the time there is no optimal code. The best option to see the diff in action is to use diff --git a/lampod-cli/src/main.rs b/lampod-cli/src/main.rs
index 5864816..c9a2d8f 100644
--- a/lampod-cli/src/main.rs
+++ b/lampod-cli/src/main.rs
@@ -48,33 +48,29 @@ fn main() -> error::Result<()> {
Ok(())
}
-fn write_words_to_file<P: AsRef<Path>>(path: P, words: Option<String>) -> io::Result<()> {
+fn write_words_to_file<P: AsRef<Path>>(path: P, words: String) -> error::Result<()> {
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)?;
- match words {
- Some(ref value) => {
- file.write_all(value.as_bytes())?;
- }
- None => {}
- }
-
+ // FIXME: we should give the possibility to encrypt this file.
+ file.write_all(words.as_bytes())?;
Ok(())
}
-fn load_words_from_file<P: AsRef<Path>>(path: P) -> io::Result<Option<String>> {
- let mut file = File::open(path)?;
+fn load_words_from_file<P: AsRef<Path>>(path: P) -> error::Result<String> {
+ let mut file = File::open(path.as_ref())?;
let mut content = String::new();
file.read_to_string(&mut content)?;
if content.is_empty() {
- Ok(None)
+ let path = path.as_ref().to_string_lossy().to_string();
+ error::bail!("The content of the wallet located at `{path}`. You lost the secret? Please report a bug this should never happens")
} else {
- Ok(Some(content))
+ Ok(content)
}
}
@@ -85,24 +81,6 @@ fn run(args: LampoCliArgs) -> error::Result<()> {
// After this point the configuration is ready!
let mut lampo_conf: LampoConf = args.try_into()?;
- let words_path = format!("{}/", lampo_conf.path());
- let mnemonic = if restore_wallet {
- if Path::new(&format!("{}/wallet.dat", words_path)).exists() {
- // Load the mnemonic from the file
- load_words_from_file(format!("{}/wallet.dat", words_path))?
- } else {
- // If file doesn't exist, ask for user input
- let inputs: String = term::input(
- "BIP 39 Mnemonic",
- None,
- Some("To restore the wallet, lampo needs the BIP39 mnemonic with words separated by spaces."),
- )?;
- Some(inputs)
- }
- } else {
- None
- };
-
log::debug!(target: "lampod-cli", "init wallet ..");
// init the logger here
logger::init(
@@ -141,47 +119,90 @@ fn run(args: LampoCliArgs) -> error::Result<()> {
_ => error::bail!("client {:?} not supported", client),
};
- let wallet = if let Some(ref _private_key) = lampo_conf.private_key {
- unimplemented!()
- } else if mnemonic.is_none() {
- let (wallet, mnemonic) = match client.kind() {
- lampo_common::backend::BackendKind::Core => {
- CoreWalletManager::new(Arc::new(lampo_conf.clone()))?
- }
- lampo_common::backend::BackendKind::Nakamoto => {
- error::bail!("wallet is not implemented for nakamoto")
- }
- };
-
- radicle_term::success!("Wallet Generated, please store these words in a safe way");
- radicle_term::println(
- radicle_term::format::badge_primary("wallet-keys"),
- format!("{}", radicle_term::format::highlight(&mnemonic)),
- );
- write_words_to_file(format!("{}/wallet.dat", words_path), Some(mnemonic))?;
- wallet
+ if let Some(ref _private_key) = lampo_conf.private_key {
+ error::bail!("Option to force a private key not available at the moment")
+ }
+
+ let words_path = format!("{}/", lampo_conf.path());
+ // There are several case in this if-else, that are:
+ // 1. lampo is running on a fresh os:
+ // 1.1: the user has a wallet, so need to specify `--restore-wallet`
+ // 1.2: the user does not have a wallet so lampo should generate a new seed for it and store it in a file.
+ // 2. lampo is running on os where there is a wallet, lampo will load the seeds from wallet:
+ // 2.1: The user keep specify --restore-wallet, so lampo should return an error an tell the user that there is already a wallet
+ // 2.2: The user do not specify the --restore-wallet, so lampo load from disk the file, if there is no file it return an error
+ // FIXME: there is a problem of code duplication here, we should move this code in utils functions.
+ let wallet = if restore_wallet {
+ if Path::new(&format!("{}/wallet.dat", words_path)).exists() {
+ // Load the mnemonic from the file
+ let mnemonic = load_words_from_file(format!("{}/wallet.dat", words_path))?;
+ let wallet = match client.kind() {
+ lampo_common::backend::BackendKind::Core => {
+ // SAFETY: It is safe to unwrap the mnemonic because we check it
+ // before.
+ CoreWalletManager::restore(Arc::new(lampo_conf.clone()), &mnemonic)?
+ }
+ lampo_common::backend::BackendKind::Nakamoto => {
+ error::bail!("wallet is not implemented for nakamoto")
+ }
+ };
+ wallet
+ } else {
+ // If file doesn't exist, ask for user input
+ let mnemonic: String = term::input(
+ "BIP 39 Mnemonic",
+ None,
+ Some("To restore the wallet, lampo needs the BIP39 mnemonic with words separated by spaces."),
+ )?;
+ // FIXME: make some sanity check about the mnemonic string
+ let wallet = match client.kind() {
+ lampo_common::backend::BackendKind::Core => {
+ // SAFETY: It is safe to unwrap the mnemonic because we check it
+ // before.
+ CoreWalletManager::restore(Arc::new(lampo_conf.clone()), &mnemonic)?
+ }
+ lampo_common::backend::BackendKind::Nakamoto => {
+ error::bail!("wallet is not implemented for nakamoto")
+ }
+ };
+
+ write_words_to_file(format!("{}/wallet.dat", words_path), mnemonic)?;
+ wallet
+ }
} else {
- match client.kind() {
- lampo_common::backend::BackendKind::Core => {
- // SAFETY: It is safe to unwrap the mnemonic because we check it
- // before.
- CoreWalletManager::restore(
- Arc::new(lampo_conf.clone()),
- &mnemonic.clone().unwrap(),
- )?
- }
- lampo_common::backend::BackendKind::Nakamoto => {
- error::bail!("wallet is not implemented for nakamoto")
- }
+ // There is a file, so we load it, and we tell the user through logs that we found it
+ if Path::new(&format!("{}/wallet.dat", words_path)).exists() {
+ // Load the mnemonic from the file
+ let mnemonic = load_words_from_file(format!("{}/wallet.dat", words_path))?;
+ let wallet = match client.kind() {
+ lampo_common::backend::BackendKind::Core => {
+ // SAFETY: It is safe to unwrap the mnemonic because we check it
+ // before.
+ CoreWalletManager::restore(Arc::new(lampo_conf.clone()), &mnemonic)?
+ }
+ lampo_common::backend::BackendKind::Nakamoto => {
+ error::bail!("wallet is not implemented for nakamoto")
+ }
+ };
+ wallet
+ } else {
+ let (wallet, mnemonic) = match client.kind() {
+ lampo_common::backend::BackendKind::Core => {
+ CoreWalletManager::new(Arc::new(lampo_conf.clone()))?
+ }
+ lampo_common::backend::BackendKind::Nakamoto => {
+ error::bail!("wallet is not implemented for nakamoto")
+ }
+ };
+
+ write_words_to_file(format!("{}/wallet.dat", words_path), mnemonic)?;
+ wallet
}
};
+
log::debug!(target: "lampod-cli", "wallet created with success");
let mut lampod = LampoDaemon::new(lampo_conf.clone(), Arc::new(wallet));
- if !Path::new(&format!("{}/wallet.dat", words_path)).exists() {
- write_words_to_file(format!("{}/wallet.dat", words_path), mnemonic)?;
- }
-
// Init the lampod
lampod.init(client)?; |
@vincenzopalazzo Looks good to me. |
This looks good and covers everything. We can go forward with this approach. But I have some suggestions:
|
This sounds good to me, thanks for the suggestion.
This is a privacy leak and we should avoid it. Then we should add a command in |
I agree! So I will go ahead with this approach and I will add the command |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok two comment and we are ready to go, sorry about the confusion here anyway!
// before. | ||
CoreWalletManager::restore(Arc::new(lampo_conf.clone()), &mnemonic)? | ||
} | ||
lampo_common::backend::BackendKind::Nakamoto => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same consideration here for a folloup PR
lampod-cli/src/main.rs
Outdated
} | ||
// If there is a file, we tell the user to use --restore-wallet | ||
if Path::new(&format!("{}/wallet.dat", words_path)).exists() { | ||
error::bail!("Wallet already exists. Please use --restore-wallet") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I reconsider my self here. This make scripting or using systemd
in linux much harder because it is not that trivial run two flavor of command.
Probably you can print a warning message here? and say that lampo is restarting an existing wallet?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another iteration and probably we are good
lampod-cli/src/main.rs
Outdated
if Path::new(&format!("{}/wallet.dat", words_path)).exists() { | ||
error::bail!("Wallet already exists. Please use --restore-wallet") | ||
// Load the mnemonic from the file | ||
radicle_term::warning("Loading from existing wallet"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, use log::warn("Loading from existing wallet");
@Psycho-Pirate when you are ready please reassign my review but I think I self review that you do yourself on the code would be good too. In addition, we need to work on how you present the git history (6 comment for a I think this is a good reading https://cbea.ms/git-commit/ and this is a bad example of commit history that cause a close of the PR #284 (comment) |
Should I also squash the commits into one? |
Up to you, the history should make sense and be easy to cherry-pick, probably this is a good reading https://www.kernel.org/doc/html/v4.10/process/submitting-patches.html#separate-your-changes |
f220ab0
to
aca1633
Compare
Squashed it to two commits for cleaner commit history |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK aca1633
Assuming that you tested out 😸
Added functionality to store words everytime new wallet is generated or wallet is restored by user.
--restore-wallet reads from the file if it exists, otherwise asks for words from user.