github.com/status-im/status-go@v1.1.0/cmd/status-cli/util.go (about)

     1  package main
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"fmt"
     7  	"os"
     8  	"strings"
     9  	"time"
    10  
    11  	"go.uber.org/zap"
    12  
    13  	"github.com/status-im/status-go/api"
    14  	"github.com/status-im/status-go/logutils"
    15  	"github.com/status-im/status-go/multiaccounts"
    16  	"github.com/status-im/status-go/params"
    17  	"github.com/status-im/status-go/protocol/requests"
    18  	"github.com/status-im/status-go/services/wakuv2ext"
    19  	"github.com/status-im/status-go/telemetry"
    20  
    21  	"github.com/urfave/cli/v2"
    22  )
    23  
    24  func setupLogger(file string) *zap.Logger {
    25  	logFile := fmt.Sprintf("%s.log", strings.ToLower(file))
    26  	logSettings := logutils.LogSettings{
    27  		Enabled:         true,
    28  		MobileSystem:    false,
    29  		Level:           "DEBUG",
    30  		File:            logFile,
    31  		MaxSize:         100,
    32  		MaxBackups:      3,
    33  		CompressRotated: true,
    34  	}
    35  	if err := logutils.OverrideRootLogWithConfig(logSettings, false); err != nil {
    36  		zap.S().Fatalf("Error initializing logger: %v", err)
    37  	}
    38  	return logutils.ZapLogger()
    39  }
    40  
    41  type StartParams struct {
    42  	Name         string
    43  	Port         int
    44  	APIModules   string
    45  	TelemetryURL string
    46  	KeyUID       string
    47  	Fleet        string
    48  }
    49  
    50  func start(p StartParams, logger *zap.SugaredLogger) (*StatusCLI, error) {
    51  	var (
    52  		rootDataDir = fmt.Sprintf("./test-%s", strings.ToLower(p.Name))
    53  		password    = "some-password"
    54  	)
    55  	setupLogger(p.Name)
    56  	logger.Info("starting messenger")
    57  
    58  	backend := api.NewGethStatusBackend()
    59  	if p.KeyUID != "" {
    60  		if err := getAccountAndLogin(backend, p.Name, rootDataDir, password, p.KeyUID); err != nil {
    61  			return nil, err
    62  		}
    63  		logger.Infof("existing account, key UID: %v", p.KeyUID)
    64  	} else {
    65  		acc, err := createAccountAndLogin(backend, rootDataDir, password, p)
    66  		if err != nil {
    67  			return nil, err
    68  		}
    69  		logger.Infof("account created, key UID: %v", acc.KeyUID)
    70  	}
    71  
    72  	wakuService := backend.StatusNode().WakuV2ExtService()
    73  	if wakuService == nil {
    74  		return nil, errors.New("waku service is not available")
    75  	}
    76  
    77  	if p.TelemetryURL != "" {
    78  		telemetryLogger, err := getLogger(true)
    79  		if err != nil {
    80  			return nil, err
    81  		}
    82  		waku := backend.StatusNode().WakuV2Service()
    83  		telemetryClient := telemetry.NewClient(telemetryLogger, p.TelemetryURL, backend.SelectedAccountKeyID(), p.Name, "cli", telemetry.WithPeerID(waku.PeerID().String()))
    84  		go telemetryClient.Start(context.Background())
    85  		backend.StatusNode().WakuV2Service().SetStatusTelemetryClient(telemetryClient)
    86  	}
    87  	wakuAPI := wakuv2ext.NewPublicAPI(wakuService)
    88  
    89  	messenger := wakuAPI.Messenger()
    90  	if _, err := wakuAPI.StartMessenger(); err != nil {
    91  		return nil, err
    92  	}
    93  
    94  	logger.Info("messenger started, public key: ", messenger.IdentityPublicKeyString())
    95  	time.Sleep(WaitingInterval)
    96  
    97  	data := StatusCLI{
    98  		name:      p.Name,
    99  		messenger: messenger,
   100  		backend:   backend,
   101  		logger:    logger,
   102  	}
   103  
   104  	return &data, nil
   105  }
   106  
   107  func getAccountAndLogin(b *api.GethStatusBackend, name, rootDataDir, password string, keyUID string) error {
   108  	b.UpdateRootDataDir(rootDataDir)
   109  	if err := b.OpenAccounts(); err != nil {
   110  		return fmt.Errorf("name '%v' might not have an account: trying to find: %v: %w", name, rootDataDir, err)
   111  	}
   112  	accs, err := b.GetAccounts()
   113  	if err != nil {
   114  		return err
   115  	}
   116  	if len(accs) == 0 {
   117  		return errors.New("no accounts found")
   118  	}
   119  
   120  	var acc multiaccounts.Account
   121  	found := false
   122  	for _, a := range accs {
   123  		if a.KeyUID == keyUID {
   124  			acc = a
   125  			found = true
   126  			break
   127  		}
   128  	}
   129  	if !found {
   130  		return fmt.Errorf("account not found for keyUID: %v", keyUID)
   131  	}
   132  
   133  	return b.LoginAccount(&requests.Login{
   134  		Password: password,
   135  		KeyUID:   acc.KeyUID,
   136  	})
   137  }
   138  
   139  func createAccountAndLogin(b *api.GethStatusBackend, rootDataDir, password string, p StartParams) (*multiaccounts.Account, error) {
   140  	if err := os.MkdirAll(rootDataDir, os.ModePerm); err != nil {
   141  		return nil, err
   142  	}
   143  
   144  	req := &requests.CreateAccount{
   145  		DisplayName:        p.Name,
   146  		CustomizationColor: "#ffffff",
   147  		Password:           password,
   148  		RootDataDir:        rootDataDir,
   149  		LogFilePath:        "log",
   150  		APIConfig: &requests.APIConfig{
   151  			APIModules:  p.APIModules,
   152  			HTTPEnabled: true,
   153  			HTTPHost:    "127.0.0.1",
   154  			HTTPPort:    p.Port,
   155  		},
   156  		TelemetryServerURL: p.TelemetryURL,
   157  	}
   158  	return b.CreateAccountAndLogin(req,
   159  		params.WithFleet(p.Fleet),
   160  		params.WithDiscV5BootstrapNodes(params.DefaultDiscV5Nodes(p.Fleet)),
   161  		params.WithWakuNodes(params.DefaultWakuNodes(p.Fleet)),
   162  	)
   163  }
   164  
   165  func (cli *StatusCLI) stop() {
   166  	err := cli.backend.StopNode()
   167  	if err != nil {
   168  		cli.logger.Error(err)
   169  	}
   170  }
   171  
   172  func getLogger(debug bool) (*zap.Logger, error) {
   173  	at := zap.NewAtomicLevel()
   174  	if debug {
   175  		at.SetLevel(zap.DebugLevel)
   176  	} else {
   177  		at.SetLevel(zap.InfoLevel)
   178  	}
   179  	config := zap.NewDevelopmentConfig()
   180  	config.Level = at
   181  	rawLogger, err := config.Build()
   182  	if err != nil {
   183  		return nil, fmt.Errorf("initializing logger: %v", err)
   184  	}
   185  	return rawLogger, nil
   186  }
   187  
   188  func getSLogger(debug bool) (*zap.SugaredLogger, error) {
   189  	l, err := getLogger(debug)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  	return l.Sugar(), nil
   194  }
   195  
   196  func flagsUsed(cCtx *cli.Context) string {
   197  	var sb strings.Builder
   198  	for _, flag := range cCtx.Command.Flags {
   199  		if flag != nil && len(flag.Names()) > 0 {
   200  			fName := flag.Names()[0]
   201  			fmt.Fprintf(&sb, "\t-%s %v\n", fName, cCtx.Value(fName))
   202  		}
   203  	}
   204  	return sb.String()
   205  }