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 }