254 lines
8.4 KiB
Go
254 lines
8.4 KiB
Go
// Copyright 2017-2021 DERO Project. All rights reserved.
|
|
// Use of this source code in any form is governed by RESEARCH license.
|
|
// license can be found in the LICENSE file.
|
|
// GPG: 0F39 E425 8C65 3947 702A 8234 08B2 0360 A03A 9DE8
|
|
//
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
|
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
|
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
|
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
|
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
package main
|
|
|
|
import "io"
|
|
import "fmt"
|
|
import "time"
|
|
import "strings"
|
|
import "encoding/hex"
|
|
|
|
import "github.com/chzyer/readline"
|
|
|
|
import "github.com/deroproject/derohe/cryptography/crypto"
|
|
import "github.com/deroproject/derohe/config"
|
|
import "github.com/deroproject/derohe/globals"
|
|
import "github.com/deroproject/derohe/walletapi"
|
|
import "github.com/deroproject/derohe/walletapi/rpcserver"
|
|
|
|
// display menu before a wallet is opened
|
|
func display_easymenu_pre_open_command(l *readline.Instance) {
|
|
w := l.Stderr()
|
|
io.WriteString(w, "Menu:\n")
|
|
io.WriteString(w, "\t\033[1m1\033[0m\tOpen existing Wallet\n")
|
|
io.WriteString(w, "\t\033[1m2\033[0m\tCreate New Wallet\n")
|
|
io.WriteString(w, "\t\033[1m3\033[0m\tRecover Wallet using recovery seed (25 words)\n")
|
|
io.WriteString(w, "\t\033[1m4\033[0m\tRecover Wallet using recovery key (64 char private spend key hex)\n")
|
|
// io.WriteString(w, "\t\033[1m5\033[0m\tCreate Watch-able Wallet (view only) using wallet view key\n")
|
|
// io.WriteString(w, "\t\033[1m6\033[0m\tRecover Non-deterministic Wallet key\n")
|
|
|
|
io.WriteString(w, "\n\t\033[1m9\033[0m\tExit menu and start prompt\n")
|
|
io.WriteString(w, "\t\033[1m0\033[0m\tExit Wallet\n")
|
|
}
|
|
|
|
// handle all commands
|
|
func handle_easymenu_pre_open_command(l *readline.Instance, line string) {
|
|
var err error
|
|
|
|
line = strings.TrimSpace(line)
|
|
line_parts := strings.Fields(line)
|
|
|
|
if len(line_parts) < 1 { // if no command return
|
|
return
|
|
}
|
|
|
|
command := ""
|
|
if len(line_parts) >= 1 {
|
|
command = strings.ToLower(line_parts[0])
|
|
}
|
|
|
|
var wallett *walletapi.Wallet_Disk
|
|
|
|
//account_state := account_valid
|
|
switch command {
|
|
case "1": // open existing wallet
|
|
filename := choose_file_name(l)
|
|
|
|
// ask user a password
|
|
for i := 0; i < 3; i++ {
|
|
wallett, err = walletapi.Open_Encrypted_Wallet(filename, ReadPassword(l, filename))
|
|
if err != nil {
|
|
logger.Error(err, "Error occurred while opening wallet file", "filename", filename)
|
|
wallet = nil
|
|
break
|
|
} else { // user knows the password and is db is valid
|
|
break
|
|
}
|
|
}
|
|
if wallett != nil {
|
|
wallet = wallett
|
|
wallett = nil
|
|
logger.Info("Successfully opened wallet")
|
|
|
|
common_processing(wallet)
|
|
}
|
|
|
|
case "2": // create a new random account
|
|
|
|
filename := choose_file_name(l)
|
|
|
|
password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
|
|
|
|
wallett, err = walletapi.Create_Encrypted_Wallet_Random(filename, password)
|
|
if err != nil {
|
|
logger.Error(err, "Error occurred while creating wallet file", "filename", filename)
|
|
wallet = nil
|
|
break
|
|
|
|
}
|
|
err = wallett.Set_Encrypted_Wallet_Password(password)
|
|
if err != nil {
|
|
logger.Error(err, "Error changing password")
|
|
}
|
|
wallet = wallett
|
|
wallett = nil
|
|
|
|
seed_language := choose_seed_language(l)
|
|
wallet.SetSeedLanguage(seed_language)
|
|
logger.V(1).Info("Seed", "Language", seed_language)
|
|
|
|
display_seed(l, wallet)
|
|
|
|
common_processing(wallet)
|
|
|
|
case "3": // create wallet from recovery words
|
|
|
|
filename := choose_file_name(l)
|
|
password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
|
|
electrum_words := read_line_with_prompt(l, "Enter seed (25 words) : ")
|
|
|
|
wallett, err = walletapi.Create_Encrypted_Wallet_From_Recovery_Words(filename, password, electrum_words)
|
|
if err != nil {
|
|
logger.Error(err, "Error while recovering wallet using seed.")
|
|
break
|
|
}
|
|
wallet = wallett
|
|
wallett = nil
|
|
//globals.Logger.Debugf("Seed Language %s", account.SeedLanguage)
|
|
logger.Info("Successfully recovered wallet from seed")
|
|
common_processing(wallet)
|
|
|
|
case "4": // create wallet from hex seed
|
|
|
|
filename := choose_file_name(l)
|
|
password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
|
|
|
|
seed_key_string := read_line_with_prompt(l, "Please enter your seed ( hex 64 chars): ")
|
|
|
|
seed_raw, err := hex.DecodeString(seed_key_string) // hex decode
|
|
if len(seed_key_string) >= 65 || err != nil { //sanity check
|
|
logger.Error(err, "Seed must be less than 66 chars hexadecimal chars")
|
|
break
|
|
}
|
|
|
|
wallett, err = walletapi.Create_Encrypted_Wallet(filename, password, new(crypto.BNRed).SetBytes(seed_raw))
|
|
if err != nil {
|
|
logger.Error(err, "Error while recovering wallet using seed key")
|
|
break
|
|
}
|
|
logger.Info("Successfully recovered wallet from hex seed")
|
|
wallet = wallett
|
|
wallett = nil
|
|
seed_language := choose_seed_language(l)
|
|
wallet.SetSeedLanguage(seed_language)
|
|
logger.V(1).Info("Seed", "Language", seed_language)
|
|
|
|
display_seed(l, wallet)
|
|
common_processing(wallet)
|
|
/*
|
|
case "5": // create new view only wallet // TODO user providing wrong key is not being validated, do it ASAP
|
|
|
|
filename := choose_file_name(l)
|
|
view_key_string := read_line_with_prompt(l, "Please enter your View Only Key ( hex 128 chars): ")
|
|
|
|
password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
|
|
wallet, err = walletapi.Create_Encrypted_Wallet_ViewOnly(filename, password, view_key_string)
|
|
|
|
if err != nil {
|
|
globals.Logger.Warnf("Error while reconstructing view only wallet using view key err %s\n", err)
|
|
break
|
|
}
|
|
|
|
if globals.Arguments["--offline"].(bool) == true {
|
|
//offline_mode = true
|
|
} else {
|
|
wallet.SetOnlineMode()
|
|
}
|
|
case "6": // create non deterministic wallet // TODO user providing wrong key is not being validated, do it ASAP
|
|
|
|
filename := choose_file_name(l)
|
|
spend_key_string := read_line_with_prompt(l, "Please enter your Secret spend key ( hex 64 chars): ")
|
|
view_key_string := read_line_with_prompt(l, "Please enter your Secret view key ( hex 64 chars): ")
|
|
|
|
password := ReadConfirmedPassword(l, "Enter password", "Confirm password")
|
|
wallet, err = walletapi.Create_Encrypted_Wallet_NonDeterministic(filename, password, spend_key_string,view_key_string)
|
|
|
|
if err != nil {
|
|
globals.Logger.Warnf("Error while reconstructing view only wallet using view key err %s\n", err)
|
|
break
|
|
}
|
|
|
|
if globals.Arguments["--offline"].(bool) == true {
|
|
//offline_mode = true
|
|
} else {
|
|
wallet.SetOnlineMode()
|
|
}
|
|
*/
|
|
case "9":
|
|
menu_mode = false
|
|
logger.Info("Prompt mode enabled")
|
|
case "0", "bye", "exit", "quit":
|
|
globals.Exit_In_Progress = true
|
|
default: // just loop
|
|
|
|
}
|
|
//_ = account_state
|
|
|
|
// NOTE: if we are in online mode, it is handled automatically
|
|
// user opened or created a new account
|
|
// rescan blockchain in offline mode
|
|
//if account_state == false && account_valid && offline_mode {
|
|
// go trigger_offline_data_scan()
|
|
//}
|
|
|
|
}
|
|
|
|
// sets online mode, starts RPC server etc
|
|
func common_processing(wallet *walletapi.Wallet_Disk) {
|
|
if globals.Arguments["--offline"].(bool) == true {
|
|
//offline_mode = true
|
|
} else {
|
|
wallet.SetOnlineMode()
|
|
}
|
|
|
|
wallet.SetNetwork(!globals.Arguments["--testnet"].(bool))
|
|
|
|
// start rpc server if requested
|
|
if globals.Arguments["--rpc-server"].(bool) == true {
|
|
rpc_address := "127.0.0.1:" + fmt.Sprintf("%d", config.Mainnet.Wallet_RPC_Default_Port)
|
|
|
|
if !globals.IsMainnet() {
|
|
rpc_address = "127.0.0.1:" + fmt.Sprintf("%d", config.Testnet.Wallet_RPC_Default_Port)
|
|
}
|
|
|
|
if globals.Arguments["--rpc-bind"] != nil {
|
|
rpc_address = globals.Arguments["--rpc-bind"].(string)
|
|
}
|
|
logger.Info("Starting RPC server", "address", rpc_address)
|
|
|
|
if _, err := rpcserver.RPCServer_Start(wallet, "walletrpc"); err != nil {
|
|
logger.Error(err, "Error starting rpc server")
|
|
|
|
}
|
|
}
|
|
time.Sleep(time.Second)
|
|
|
|
// init_script_engine(wallet) // init script engine
|
|
// init_plugins_engine(wallet) // init script engine
|
|
|
|
}
|