chore: refactor status cli (#5010)

* chore: remove opts when create account

* chore: namings and better logging

* chore: config api modules with flag.

* chore: renaming

* chore: use methods on object

* fix: allow less characters for name

* fix: display name unit test

* chore: revert display name check.

* chore: change simulate display name.
This commit is contained in:
kaichao 2024-04-09 18:44:43 +03:00 committed by GitHub
parent 69326767d8
commit e2a4a22896
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 106 additions and 100 deletions

View File

@ -190,7 +190,7 @@ func buildWalletConfig(request *requests.WalletSecretsConfig) params.WalletConfi
return walletConfig
}
func defaultNodeConfig(installationID string, request *requests.CreateAccount, opts ...params.Option) (*params.NodeConfig, error) {
func defaultNodeConfig(installationID string, request *requests.CreateAccount) (*params.NodeConfig, error) {
// Set mainnet
nodeConfig := &params.NodeConfig{}
nodeConfig.LogEnabled = request.LogEnabled
@ -311,10 +311,11 @@ func defaultNodeConfig(installationID string, request *requests.CreateAccount, o
nodeConfig.TorrentConfig.Port = *request.TorrentConfigPort
}
for _, opt := range opts {
if err := opt(nodeConfig); err != nil {
return nil, err
}
if request.APIConfig != nil {
nodeConfig.HTTPEnabled = true
nodeConfig.HTTPHost = request.APIConfig.HTTPHost
nodeConfig.HTTPPort = request.APIConfig.HTTPPort
nodeConfig.APIModules = request.APIConfig.APIModules
}
return nodeConfig, nil

View File

@ -1302,7 +1302,7 @@ func (b *GethStatusBackend) GetKeyUIDByMnemonic(mnemonic string) (string, error)
return info.KeyUID, nil
}
func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizationColorClock uint64, fetchBackup bool, request *requests.CreateAccount, opts ...params.Option) (*multiaccounts.Account, error) {
func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizationColorClock uint64, fetchBackup bool, request *requests.CreateAccount) (*multiaccounts.Account, error) {
keystoreDir := keystoreRelativePath
b.UpdateRootDataDir(request.BackupDisabledDataDir)
@ -1405,7 +1405,7 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati
//settings.MnemonicWasNotShown = true
}
nodeConfig, err := defaultNodeConfig(settings.InstallationID, request, opts...)
nodeConfig, err := defaultNodeConfig(settings.InstallationID, request)
if err != nil {
return nil, err
}
@ -1453,14 +1453,14 @@ func (b *GethStatusBackend) generateOrImportAccount(mnemonic string, customizati
return &account, nil
}
func (b *GethStatusBackend) CreateAccountAndLogin(request *requests.CreateAccount, opts ...params.Option) (*multiaccounts.Account, error) {
func (b *GethStatusBackend) CreateAccountAndLogin(request *requests.CreateAccount) (*multiaccounts.Account, error) {
validation := &requests.CreateAccountValidation{
AllowEmptyDisplayName: false,
}
if err := request.Validate(validation); err != nil {
return nil, err
}
return b.generateOrImportAccount("", 1, false, request, opts...)
return b.generateOrImportAccount("", 1, false, request)
}
func (b *GethStatusBackend) ConvertToRegularAccount(mnemonic string, currPassword string, newPassword string) error {

View File

@ -26,8 +26,8 @@ You can also run `make status-cli` in the root directory to build the binary.
# run alice's server
./status-cli serve
# run Bob's server in another terminal with the logged pubkey of Alice
./status-cli serve -n bob -p 8565 -a <alice-pubkey>
# run charlie's server in another terminal with the logged pubkey of Alice
./status-cli serve -n charlie -p 8565 -a <alice-pubkey>
```
You can send direct messages through terminal or JSON RPC.
@ -38,31 +38,31 @@ JSON RPC examples:
# get waku info
curl -XPOST http://127.0.0.1:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"waku_info","params":[],"id":1}'
# send contact request from bob to alice (use -a flag will automatacally send contact request when starting)
# send contact request from charlie to alice (use -a flag will automatacally send contact request when starting)
curl -XPOST http://127.0.0.1:8565 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendContactRequest","params":[{"id": "0x0436470da23039f10c1588bc6b9fcbd4b815bf9fae4dc09c0fb05a7eaaf1670b5dbdbc757630d54bf2f8be45a796304dc42506c3f4172f499f610a9ed85d9b0d4c", "message": "hello"}],"id":1}'
# send dm from bob to alice
# send dm from charlie to alice
curl -XPOST http://127.0.0.1:8565 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendOneToOneMessage","params":[{"id": "0x0436470da23039f10c1588bc6b9fcbd4b815bf9fae4dc09c0fb05a7eaaf1670b5dbdbc757630d54bf2f8be45a796304dc42506c3f4172f499f610a9ed85d9b0d4c", "message": "how are you"}],"id":1}'
# send dm from alice to bob
# send dm from alice to charlie
curl -XPOST http://127.0.0.1:8545 -H 'Content-type: application/json' -d '{"jsonrpc":"2.0","method":"wakuext_sendOneToOneMessage","params":[{"id": "0x042c0ce856c41ad6d3f651a84c83f646cdafdf3a26a3d69bce3a6ccf59b23b5a366c12162045d5066abad7912741a6e6c6e8e11e7826c4c850a1de7a2bae24a79c", "message": "Im fine, and you?"}],"id":1}'
```
### Run `dm` command:
### Run `simulate` command:
```bash
# simulate DM between two accounts
./status-cli dm
./status-cli simulate
# simulate DM in a interactive way
./status-cli dm -i
./status-cli simulate -i
# simulate DM with 3 messages
./status-cli dm -c 3
./status-cli simulate -c 3
# run in light mode
./status-cli dm --light
./status-cli simulate --light
```
You can run the commands with `--light` to work as a light client.

View File

@ -18,6 +18,7 @@ const CountFlag = "count"
const NameFlag = "name"
const AddFlag = "add"
const PortFlag = "port"
const APIModulesFlag = "api-modules"
const RetrieveInterval = 300 * time.Millisecond
const SendInterval = 1 * time.Second
@ -29,13 +30,19 @@ var CommonFlags = []cli.Flag{
Aliases: []string{"l"},
Usage: "Enable light mode",
},
&cli.StringFlag{
Name: APIModulesFlag,
Aliases: []string{"m"},
Value: "waku,wakuext,wakuv2,permissions,eth",
Usage: "API modules to enable",
},
}
var DmFlags = append([]cli.Flag{
var SimulateFlags = append([]cli.Flag{
&cli.BoolFlag{
Name: InteractiveFlag,
Aliases: []string{"i"},
Usage: "Use interactive mode",
Usage: "Use interactive mode to input the messages",
},
&cli.IntFlag{
Name: CountFlag,
@ -78,10 +85,9 @@ func main() {
app := &cli.App{
Commands: []*cli.Command{
{
Name: "dm",
Aliases: []string{"d"},
Usage: "Send direct message",
Flags: DmFlags,
Name: "simulate",
Usage: "Simulate the process of sending direct messages",
Flags: SimulateFlags,
Action: func(cCtx *cli.Context) error {
return simulate(cCtx)
},

View File

@ -16,14 +16,14 @@ import (
"github.com/urfave/cli/v2"
)
func sendContactRequest(cCtx *cli.Context, from *StatusCLI, toID string) error {
from.logger.Info("send contact request, contact public key: ", toID)
func (cli *StatusCLI) sendContactRequest(cCtx *cli.Context, toID string) error {
cli.logger.Info("send contact request, contact public key: ", toID)
request := &requests.SendContactRequest{
ID: toID,
Message: "Hello!",
}
resp, err := from.messenger.SendContactRequest(cCtx.Context, request)
from.logger.Info("function SendContactRequest response.messages: ", resp.Messages())
resp, err := cli.messenger.SendContactRequest(cCtx.Context, request)
cli.logger.Info("function SendContactRequest response.messages: ", resp.Messages())
if err != nil {
return err
}
@ -31,25 +31,25 @@ func sendContactRequest(cCtx *cli.Context, from *StatusCLI, toID string) error {
return nil
}
func sendContactRequestAcceptance(cCtx *cli.Context, from *StatusCLI, msgID string) error {
from.logger.Info("accept contact request, message ID: ", msgID)
resp, err := from.messenger.AcceptContactRequest(cCtx.Context, &requests.AcceptContactRequest{ID: types.Hex2Bytes(msgID)})
func (cli *StatusCLI) sendContactRequestAcceptance(cCtx *cli.Context, msgID string) error {
cli.logger.Info("accept contact request, message ID: ", msgID)
resp, err := cli.messenger.AcceptContactRequest(cCtx.Context, &requests.AcceptContactRequest{ID: types.Hex2Bytes(msgID)})
if err != nil {
return err
}
from.logger.Info("function AcceptContactRequest response: ", resp.Messages())
cli.logger.Info("function AcceptContactRequest response: ", resp.Messages())
return nil
}
func sendDirectMessage(ctx context.Context, from *StatusCLI, text string) error {
if len(from.messenger.MutualContacts()) == 0 {
func (cli *StatusCLI) sendDirectMessage(ctx context.Context, text string) error {
if len(cli.messenger.MutualContacts()) == 0 {
return nil
}
chat := from.messenger.Chat(from.messenger.MutualContacts()[0].ID)
from.logger.Info("send message to contact: ", chat.ID)
chat := cli.messenger.Chat(cli.messenger.MutualContacts()[0].ID)
cli.logger.Info("send message to contact: ", chat.ID)
clock, timestamp := chat.NextClockAndTimestamp(from.messenger.GetTransport())
clock, timestamp := chat.NextClockAndTimestamp(cli.messenger.GetTransport())
inputMessage := common.NewMessage()
inputMessage.ChatId = chat.ID
inputMessage.LocalChatID = chat.ID
@ -59,7 +59,7 @@ func sendDirectMessage(ctx context.Context, from *StatusCLI, text string) error
inputMessage.ContentType = protobuf.ChatMessage_TEXT_PLAIN
inputMessage.Text = text
_, err := from.messenger.SendChatMessage(ctx, inputMessage)
_, err := cli.messenger.SendChatMessage(ctx, inputMessage)
if err != nil {
return err
}
@ -67,7 +67,7 @@ func sendDirectMessage(ctx context.Context, from *StatusCLI, text string) error
return nil
}
func retrieveMessagesLoop(ctx context.Context, cli *StatusCLI, tick time.Duration, msgCh chan string, wg *sync.WaitGroup) {
func (cli *StatusCLI) retrieveMessagesLoop(ctx context.Context, tick time.Duration, msgCh chan string, wg *sync.WaitGroup) {
defer wg.Done()
ticker := time.NewTicker(tick)
@ -83,21 +83,22 @@ func retrieveMessagesLoop(ctx context.Context, cli *StatusCLI, tick time.Duratio
cli.logger.Error("failed to retrieve raw messages", "err", err)
continue
}
if response != nil && len(response.Messages()) != 0 {
if response == nil {
continue
}
for _, message := range response.Messages() {
cli.logger.Info("receive message: ", message.Text)
cli.logger.Info("message received: ", message.Text)
if message.ContentType == protobuf.ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_SENT {
msgCh <- message.ID
}
}
}
case <-ctx.Done():
return
}
}
}
func sendMessageLoop(ctx context.Context, cli *StatusCLI, tick time.Duration, wg *sync.WaitGroup, sem chan struct{}, cancel context.CancelFunc) {
func (cli *StatusCLI) sendMessageLoop(ctx context.Context, tick time.Duration, wg *sync.WaitGroup, sem chan struct{}, cancel context.CancelFunc) {
defer wg.Done()
ticker := time.NewTicker(tick)
@ -130,7 +131,7 @@ func sendMessageLoop(ctx context.Context, cli *StatusCLI, tick time.Duration, wg
continue
}
err = sendDirectMessage(ctx, cli, message)
err = cli.sendDirectMessage(ctx, message)
time.Sleep(WaitingInterval)
<-sem
if err != nil {

View File

@ -35,24 +35,25 @@ func serve(cCtx *cli.Context) error {
name := cCtx.String(NameFlag)
port := cCtx.Int(PortFlag)
apiModules := cCtx.String(APIModulesFlag)
messenger, err := startMessenger(cCtx, name, port)
cli, err := start(cCtx, name, port, apiModules)
if err != nil {
return err
}
defer stopMessenger(messenger)
defer cli.stop()
// Retrieve for messages
var wg sync.WaitGroup
msgCh := make(chan string)
wg.Add(1)
go retrieveMessagesLoop(ctx, messenger, RetrieveInterval, msgCh, &wg)
go cli.retrieveMessagesLoop(ctx, RetrieveInterval, msgCh, &wg)
// Send contact request from Alice to Bob, bob accept the request
// Send and accept contact request
dest := cCtx.String(AddFlag)
if dest != "" {
err := sendContactRequest(cCtx, messenger, dest)
err := cli.sendContactRequest(cCtx, dest)
if err != nil {
return err
}
@ -60,7 +61,7 @@ func serve(cCtx *cli.Context) error {
go func() {
msgID := <-msgCh
err = sendContactRequestAcceptance(cCtx, messenger, msgID)
err = cli.sendContactRequestAcceptance(cCtx, msgID)
if err != nil {
logger.Error(err)
return
@ -70,7 +71,7 @@ func serve(cCtx *cli.Context) error {
// Send message if mutual contact exists
sem := make(chan struct{}, 1)
wg.Add(1)
go sendMessageLoop(ctx, messenger, SendInterval, &wg, sem, cancel)
go cli.sendMessageLoop(ctx, SendInterval, &wg, sem, cancel)
wg.Wait()
logger.Info("Exiting")

View File

@ -2,6 +2,7 @@ package main
import (
"context"
"fmt"
"log"
"os"
"os/signal"
@ -9,9 +10,6 @@ import (
"syscall"
"time"
"github.com/ethereum/go-ethereum/crypto"
"github.com/status-im/status-go/eth-node/types"
"github.com/urfave/cli/v2"
"go.uber.org/zap"
)
@ -32,65 +30,67 @@ func simulate(cCtx *cli.Context) error {
}
logger = rawLogger.Sugar()
logger.Info("Running dm command, flags passed:")
for _, flag := range DmFlags {
logger.Info("Running simulate command, flags passed:")
for _, flag := range SimulateFlags {
logger.Infof("-%s %v", flag.Names()[0], cCtx.Value(flag.Names()[0]))
}
// Start Alice and Bob's messengers
alice, err := startMessenger(cCtx, "Alice", 0)
if err != nil {
return err
}
defer stopMessenger(alice)
// Start messengers
apiModules := cCtx.String(APIModulesFlag)
bob, err := startMessenger(cCtx, "Bob", 0)
alice, err := start(cCtx, "Alice", 0, apiModules)
if err != nil {
return err
}
defer stopMessenger(bob)
defer alice.stop()
charlie, err := start(cCtx, "Charlie", 0, apiModules)
if err != nil {
return err
}
defer charlie.stop()
// Retrieve for messages
msgCh := make(chan string)
var wg sync.WaitGroup
wg.Add(1)
go retrieveMessagesLoop(ctx, alice, RetrieveInterval, nil, &wg)
go alice.retrieveMessagesLoop(ctx, RetrieveInterval, nil, &wg)
wg.Add(1)
go retrieveMessagesLoop(ctx, bob, RetrieveInterval, msgCh, &wg)
go charlie.retrieveMessagesLoop(ctx, RetrieveInterval, msgCh, &wg)
// Send contact request from Alice to Bob, bob accept the request
// Send contact request from Alice to Charlie, charlie accept the request
time.Sleep(WaitingInterval)
destID := types.EncodeHex(crypto.FromECDSAPub(bob.messenger.IdentityPublicKey()))
err = sendContactRequest(cCtx, alice, destID)
destID := charlie.messenger.GetSelfContact().ID
err = alice.sendContactRequest(cCtx, destID)
if err != nil {
return err
}
msgID := <-msgCh
err = sendContactRequestAcceptance(cCtx, bob, msgID)
err = charlie.sendContactRequestAcceptance(cCtx, msgID)
if err != nil {
return err
}
// Send DM between alice to bob
// Send DM between alice to charlie
interactive := cCtx.Bool(InteractiveFlag)
if interactive {
sem := make(chan struct{}, 1)
wg.Add(1)
go sendMessageLoop(ctx, alice, SendInterval, &wg, sem, cancel)
go alice.sendMessageLoop(ctx, SendInterval, &wg, sem, cancel)
wg.Add(1)
go sendMessageLoop(ctx, bob, SendInterval, &wg, sem, cancel)
go charlie.sendMessageLoop(ctx, SendInterval, &wg, sem, cancel)
} else {
time.Sleep(WaitingInterval)
for i := 0; i < cCtx.Int(CountFlag); i++ {
err = sendDirectMessage(ctx, alice, "hello bob :)")
err = alice.sendDirectMessage(ctx, fmt.Sprintf("message from alice, number: %d", i+1))
if err != nil {
return err
}
time.Sleep(WaitingInterval)
err = sendDirectMessage(ctx, bob, "hello Alice ~")
err = charlie.sendDirectMessage(ctx, fmt.Sprintf("message from charlie, number: %d", i+1))
if err != nil {
return err
}

View File

@ -9,7 +9,6 @@ import (
"github.com/status-im/status-go/api"
"github.com/status-im/status-go/logutils"
"github.com/status-im/status-go/params"
"github.com/status-im/status-go/protocol/requests"
"github.com/status-im/status-go/services/wakuv2ext"
@ -32,23 +31,10 @@ func setupLogger(file string) *zap.Logger {
logger.Fatalf("Error initializing logger: %v", err)
}
newLogger := logutils.ZapLogger()
return newLogger
return logutils.ZapLogger()
}
func withHTTP(port int) params.Option {
return func(c *params.NodeConfig) error {
c.APIModules = "waku,wakuext,wakuv2,permissions,eth"
c.HTTPEnabled = true
c.HTTPHost = "127.0.0.1"
c.HTTPPort = port
return nil
}
}
func startMessenger(cCtx *cli.Context, name string, port int) (*StatusCLI, error) {
func start(cCtx *cli.Context, name string, port int, apiModules string) (*StatusCLI, error) {
namedLogger := logger.Named(name)
namedLogger.Info("starting messager")
@ -63,15 +49,19 @@ func startMessenger(cCtx *cli.Context, name string, port int) (*StatusCLI, error
backend := api.NewGethStatusBackend()
createAccountRequest := &requests.CreateAccount{
DisplayName: "some-display-name",
DisplayName: name,
CustomizationColor: "#ffffff",
Emoji: "some",
Password: "some-password",
BackupDisabledDataDir: fmt.Sprintf("./test-%s", strings.ToLower(name)),
LogFilePath: "log",
APIConfig: &requests.APIConfig{
APIModules: apiModules,
HTTPHost: "127.0.0.1",
HTTPPort: port,
},
}
opts := []params.Option{withHTTP(port)}
_, err = backend.CreateAccountAndLogin(createAccountRequest, opts...)
_, err = backend.CreateAccountAndLogin(createAccountRequest)
if err != nil {
return nil, err
}
@ -102,7 +92,7 @@ func startMessenger(cCtx *cli.Context, name string, port int) (*StatusCLI, error
return &data, nil
}
func stopMessenger(cli *StatusCLI) {
func (cli *StatusCLI) stop() {
err := cli.backend.StopNode()
if err != nil {
logger.Error(err)

View File

@ -220,5 +220,4 @@ func (s *MessengerProfileDisplayNameHandlerSuite) TestDisplayNameRestrictions()
displayName, err = s.m.settings.DisplayName()
s.Require().NoError(err)
s.Require().Equal("name with space", displayName)
}

View File

@ -19,6 +19,12 @@ type ImageCropRectangle struct {
By int `json:"by"`
}
type APIConfig struct {
APIModules string `json:"apiModules"`
HTTPHost string `json:"httpHost"`
HTTPPort int `json:"httpPort"`
}
type CreateAccount struct {
// BackupDisabledDataDir is the directory where backup is disabled
// WARNING: This is used as `RootDataDir`. Consider renaming?
@ -59,6 +65,8 @@ type CreateAccount struct {
TorrentConfigEnabled *bool
TorrentConfigPort *int
APIConfig *APIConfig `json:"apiConfig"`
}
type WalletSecretsConfig struct {