package main import ( "encoding/json" "fmt" "os" "os/user" "path/filepath" "strings" "github.com/ark-network/ark/common" "github.com/urfave/cli/v2" ) const ( DATADIR_ENVVAR = "NOAH_DATADIR" STATE_FILE = "state.json" defaultArkURL = "ark://apub1qgvdtj5ttpuhkldavhq8thtm5auyk0ec4dcmrfdgu0u5hgp9we22v3hrs4x?relays=arelay1qt6f8p7h5f6tm7fv2z5wg92sz92rn9desfhd5733se4lkrptqtdrq65987l-arelay1qt6f8p7h5f6tm7fv2z5wg92sz92rn9desfhd5733se4lkrptqtdrq65987l" ) var ( version = "alpha" noahDataDirectory = common.AppDataDir("noah", false) statePath = filepath.Join(noahDataDirectory, STATE_FILE) initialState = map[string]string{ "ark_url": defaultArkURL, "ark_pubkey": "", "encrypted_private_key": "", "password_hash": "", "public_key": "", "network": "mainnet", } ) func initCLIEnv() { dataDir := cleanAndExpandPath(os.Getenv(DATADIR_ENVVAR)) if len(dataDir) <= 0 { return } noahDataDirectory = dataDir statePath = filepath.Join(noahDataDirectory, STATE_FILE) } func main() { initCLIEnv() app := cli.NewApp() app.Version = version app.Name = "noah CLI" app.Usage = "Command line interface for Ark wallet" app.Commands = append( app.Commands, &balanceCommand, &configCommand, &faucetCommand, &initCommand, &receiveCommand, &redeemCommand, &sendCommand, ) app.Before = func(ctx *cli.Context) error { if _, err := os.Stat(noahDataDirectory); os.IsNotExist(err) { return os.Mkdir(noahDataDirectory, os.ModeDir|0755) } return nil } err := app.Run(os.Args) if err != nil { fmt.Println(fmt.Errorf("error: %v", err)) os.Exit(1) } } // cleanAndExpandPath expands environment variables and leading ~ in the // passed path, cleans the result, and returns it. // This function is taken from https://github.com/btcsuite/btcd func cleanAndExpandPath(path string) string { if path == "" { return "" } // Expand initial ~ to OS specific home directory. if strings.HasPrefix(path, "~") { var homeDir string u, err := user.Current() if err == nil { homeDir = u.HomeDir } else { homeDir = os.Getenv("HOME") } path = strings.Replace(path, "~", homeDir, 1) } // NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%, // but the variables can still be expanded via POSIX-style $VARIABLE. return filepath.Clean(os.ExpandEnv(path)) } func getState() (map[string]string, error) { file, err := os.ReadFile(statePath) if err != nil { if !os.IsNotExist(err) { return nil, err } if err := setInitialState(); err != nil { return nil, err } return initialState, nil } data := map[string]string{} if err := json.Unmarshal(file, &data); err != nil { return nil, err } return data, nil } func setInitialState() error { jsonString, err := json.Marshal(initialState) if err != nil { return err } return os.WriteFile(statePath, jsonString, 0755) } func setState(data map[string]string) error { currentData, err := getState() if err != nil { return err } mergedData := merge(currentData, data) jsonString, err := json.Marshal(mergedData) if err != nil { return err } err = os.WriteFile(statePath, jsonString, 0755) if err != nil { return fmt.Errorf("writing to file: %w", err) } return nil } func merge(maps ...map[string]string) map[string]string { merge := make(map[string]string, 0) for _, m := range maps { for k, v := range m { merge[k] = v } } return merge }