github.com/deroproject/derosuite@v2.1.6-1.0.20200307070847-0f2e589c7a2b+incompatible/cmd/dero-wallet-cli/easymenu_pre_open.go (about)

     1  // Copyright 2017-2018 DERO Project. All rights reserved.
     2  // Use of this source code in any form is governed by RESEARCH license.
     3  // license can be found in the LICENSE file.
     4  // GPG: 0F39 E425 8C65 3947 702A  8234 08B2 0360 A03A 9DE8
     5  //
     6  //
     7  // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
     8  // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     9  // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
    10  // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    11  // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    12  // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    13  // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    14  // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
    15  // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    16  
    17  package main
    18  
    19  import "io"
    20  import "fmt"
    21  import "strings"
    22  import "encoding/hex"
    23  
    24  import "github.com/chzyer/readline"
    25  
    26  import "github.com/deroproject/derosuite/crypto"
    27  import "github.com/deroproject/derosuite/config"
    28  import "github.com/deroproject/derosuite/globals"
    29  import "github.com/deroproject/derosuite/walletapi"
    30  
    31  // display menu before a wallet is opened
    32  func display_easymenu_pre_open_command(l *readline.Instance) {
    33  	w := l.Stderr()
    34  	io.WriteString(w, "Menu:\n")
    35  	io.WriteString(w, "\t\033[1m1\033[0m\tOpen existing Wallet\n")
    36  	io.WriteString(w, "\t\033[1m2\033[0m\tCreate New Wallet\n")
    37  	io.WriteString(w, "\t\033[1m3\033[0m\tRecover Wallet using recovery seed (25 words)\n")
    38  	io.WriteString(w, "\t\033[1m4\033[0m\tRecover Wallet using recovery key (64 char private spend key hex)\n")
    39  	io.WriteString(w, "\t\033[1m5\033[0m\tCreate  Watch-able Wallet (view only) using wallet view key\n")
    40          io.WriteString(w, "\t\033[1m6\033[0m\tRecover Non-deterministic Wallet key\n")
    41  
    42  	io.WriteString(w, "\n\t\033[1m9\033[0m\tExit menu and start prompt\n")
    43  	io.WriteString(w, "\t\033[1m0\033[0m\tExit Wallet\n")
    44  }
    45  
    46  // handle all commands
    47  func handle_easymenu_pre_open_command(l *readline.Instance, line string) {
    48  	var err error
    49  
    50  	line = strings.TrimSpace(line)
    51  	line_parts := strings.Fields(line)
    52  
    53  	if len(line_parts) < 1 { // if no command return
    54  		return
    55  	}
    56  
    57  	command := ""
    58  	if len(line_parts) >= 1 {
    59  		command = strings.ToLower(line_parts[0])
    60  	}
    61  
    62  	//account_state := account_valid
    63  	switch command {
    64  	case "1": // open existing wallet
    65  		filename := choose_file_name(l)
    66  
    67  		// ask user a password
    68  		for i := 0; i < 3; i++ {
    69  			wallet, err = walletapi.Open_Encrypted_Wallet(filename, ReadPassword(l, filename))
    70  			if err != nil {
    71  				globals.Logger.Warnf("Error occurred while opening wallet file %s. err %s", filename, err)
    72  				wallet = nil
    73  				break
    74  			} else { //  user knows the password and is db is valid
    75  				break
    76  			}
    77  		}
    78  		if wallet != nil {
    79  			globals.Logger.Infof("Successfully opened wallet")
    80  
    81  			common_processing(wallet)
    82  		}
    83  
    84  	case "2": // create a new random account
    85  
    86  		filename := choose_file_name(l)
    87  
    88  		password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
    89  
    90  		wallet, err = walletapi.Create_Encrypted_Wallet_Random(filename, password)
    91  		if err != nil {
    92  			globals.Logger.Warnf("Error occured while creating new wallet, err: %s", err)
    93  			wallet = nil
    94  			break
    95  
    96  		}
    97  		err = wallet.Set_Encrypted_Wallet_Password(password)
    98  		if err != nil {
    99  			globals.Logger.Warnf("Error changing password")
   100  		}
   101  		seed_language := choose_seed_language(l)
   102  		wallet.SetSeedLanguage(seed_language)
   103  		globals.Logger.Debugf("Seed Language %s", seed_language)
   104  
   105  		display_seed(l, wallet)
   106  
   107  		common_processing(wallet)
   108  
   109  	case "3": // create wallet from recovery words
   110  
   111  		filename := choose_file_name(l)
   112  		password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
   113  		electrum_words := read_line_with_prompt(l, "Enter seed (25 words) : ")
   114  
   115  		wallet, err = walletapi.Create_Encrypted_Wallet_From_Recovery_Words(filename, password, electrum_words)
   116  		if err != nil {
   117  			globals.Logger.Warnf("Error while recovering wallet using seed err %s\n", err)
   118  			break
   119  		}
   120  		//globals.Logger.Debugf("Seed Language %s", account.SeedLanguage)
   121  		globals.Logger.Infof("Successfully recovered wallet from seed")
   122  		common_processing(wallet)
   123  
   124  	case "4": // create wallet from  hex seed
   125  
   126  		var seedkey crypto.Key
   127  		filename := choose_file_name(l)
   128  		password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
   129  
   130  		seed_key_string := read_line_with_prompt(l, "Please enter your seed ( hex 64 chars): ")
   131  
   132  		seed_raw, err := hex.DecodeString(seed_key_string) // hex decode
   133  		if len(seed_key_string) != 64 || err != nil {      //sanity check
   134  			globals.Logger.Warnf("Seed must be 64 chars hexadecimal chars")
   135  			break
   136  		}
   137  
   138  		copy(seedkey[:], seed_raw[:32])
   139  
   140  		wallet, err = walletapi.Create_Encrypted_Wallet(filename, password, seedkey)
   141  		if err != nil {
   142  			globals.Logger.Warnf("Error while recovering wallet using seed key err %s\n", err)
   143  			break
   144  		}
   145  		globals.Logger.Infof("Successfully recovered wallet from hex seed")
   146  		seed_language := choose_seed_language(l)
   147  		wallet.SetSeedLanguage(seed_language)
   148  		globals.Logger.Debugf("Seed Language %s", seed_language)
   149  
   150  		display_seed(l, wallet)
   151  		common_processing(wallet)
   152  
   153  	case "5": // create new view only wallet // TODO user providing wrong key is not being validated, do it ASAP
   154  
   155  		filename := choose_file_name(l)
   156  		view_key_string := read_line_with_prompt(l, "Please enter your View Only Key ( hex 128 chars): ")
   157  
   158  		password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
   159  		wallet, err = walletapi.Create_Encrypted_Wallet_ViewOnly(filename, password, view_key_string)
   160  
   161  		if err != nil {
   162  			globals.Logger.Warnf("Error while reconstructing view only wallet using view key err %s\n", err)
   163  			break
   164  		}
   165  
   166  		if globals.Arguments["--offline"].(bool) == true {
   167  			//offline_mode = true
   168  		} else {
   169  			wallet.SetOnlineMode()
   170  		}
   171          case "6": // create non deterministic wallet // TODO user providing wrong key is not being validated, do it ASAP
   172  
   173  		filename := choose_file_name(l)
   174  		spend_key_string := read_line_with_prompt(l, "Please enter your Secret spend key ( hex 64 chars): ")
   175                  view_key_string := read_line_with_prompt(l, "Please enter your Secret view key ( hex 64 chars): ")
   176  
   177  		password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
   178  		wallet, err = walletapi.Create_Encrypted_Wallet_NonDeterministic(filename, password, spend_key_string,view_key_string)
   179  
   180  		if err != nil {
   181  			globals.Logger.Warnf("Error while reconstructing view only wallet using view key err %s\n", err)
   182  			break
   183  		}
   184  
   185  		if globals.Arguments["--offline"].(bool) == true {
   186  			//offline_mode = true
   187  		} else {
   188  			wallet.SetOnlineMode()
   189  		}
   190  
   191  	case "9":
   192  		menu_mode = false
   193  		globals.Logger.Infof("Prompt mode enabled")
   194  	case "0", "bye", "exit", "quit":
   195  		globals.Exit_In_Progress = true
   196  	default: // just loop
   197  
   198  	}
   199  	//_ = account_state
   200  
   201  	// NOTE: if we are in online mode, it is handled automatically
   202  	// user opened or created a new account
   203  	// rescan blockchain in offline mode
   204  	//if account_state == false && account_valid && offline_mode {
   205  	//	go trigger_offline_data_scan()
   206  	//}
   207  
   208  }
   209  
   210  // sets online mode, starts RPC server etc
   211  func common_processing(wallet *walletapi.Wallet) {
   212  	if globals.Arguments["--offline"].(bool) == true {
   213  		//offline_mode = true
   214  	} else {
   215  		wallet.SetOnlineMode()
   216  	}
   217  
   218  	// start rpc server if requested
   219  	if globals.Arguments["--rpc-server"].(bool) == true {
   220  		rpc_address := "127.0.0.1:" + fmt.Sprintf("%d", config.Mainnet.Wallet_RPC_Default_Port)
   221  
   222  		if !globals.IsMainnet() {
   223  			rpc_address = "127.0.0.1:" + fmt.Sprintf("%d", config.Testnet.Wallet_RPC_Default_Port)
   224  		}
   225  
   226  		if globals.Arguments["--rpc-bind"] != nil {
   227  			rpc_address = globals.Arguments["--rpc-bind"].(string)
   228  		}
   229  		globals.Logger.Infof("Starting RPC server at %s", rpc_address)
   230  		err := wallet.Start_RPC_Server(rpc_address)
   231  		if err != nil {
   232  			globals.Logger.Warnf("Error starting rpc server err %s", err)
   233  
   234  		}
   235  
   236  	}
   237  
   238  }