diff --git a/cmd/consts/consts.go b/cmd/consts/consts.go index c3d8e5e2..acd1ff11 100644 --- a/cmd/consts/consts.go +++ b/cmd/consts/consts.go @@ -41,6 +41,7 @@ var KeysIds = struct { RollappRelayer string HubRelayer string Celestia string + Eibc string }{ HubSequencer: "hub_sequencer", HubGenesis: "hub_genesis", @@ -48,6 +49,7 @@ var KeysIds = struct { RollappRelayer: "relayer-rollapp-key", HubRelayer: "relayer-hub-key", Celestia: "my_celes_key", + Eibc: "whale", } var AddressPrefixes = struct { @@ -69,7 +71,7 @@ var ConfigDirName = struct { DALightNode: "da-light-node", HubKeys: "hub-keys", LocalHub: "local-hub", - Eibc: ".order-client", + Eibc: ".eibc-client", } var Denoms = struct { diff --git a/cmd/eibc/init.go b/cmd/eibc/init.go index 97c415ad..b58eb9f0 100644 --- a/cmd/eibc/init.go +++ b/cmd/eibc/init.go @@ -2,16 +2,22 @@ package eibc import ( "fmt" - "log" "os" "os/exec" "path/filepath" + "github.com/pterm/pterm" "github.com/spf13/cobra" + yaml "gopkg.in/yaml.v3" + initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/consts" - global_utils "github.com/dymensionxyz/roller/utils" + "github.com/dymensionxyz/roller/cmd/utils" + globalutils "github.com/dymensionxyz/roller/utils" "github.com/dymensionxyz/roller/utils/bash" + "github.com/dymensionxyz/roller/utils/config/tomlconfig" + "github.com/dymensionxyz/roller/utils/config/yamlconfig" + "github.com/dymensionxyz/roller/utils/errorhandling" ) func initCmd() *cobra.Command { @@ -19,18 +25,63 @@ func initCmd() *cobra.Command { Use: "init", Short: "Initialize eibc client", Run: func(cmd *cobra.Command, args []string) { - home, _ := os.UserHomeDir() - eibcHome := filepath.Join(home, ".order-client") - ok, err := global_utils.DirNotEmpty(eibcHome) + err := initconfig.AddFlags(cmd) if err != nil { + pterm.Error.Println("failed to add flags") return } - if ok { - fmt.Println("eibc client already initialized") + rollerHome, err := globalutils.ExpandHomePath( + cmd.Flag(utils.FlagNames.Home).Value.String(), + ) + if err != nil { + pterm.Error.Println("failed to expand home directory") return } + home, err := os.UserHomeDir() + if err != nil { + pterm.Error.Println("failed to get user home dir", err) + } + + rollerConfig, err := tomlconfig.LoadRollerConfig(rollerHome) + if err != nil { + return + } + + eibcHome := filepath.Join(home, consts.ConfigDirName.Eibc) + isEibcClientInitialized, err := globalutils.DirNotEmpty(eibcHome) + if err != nil { + pterm.Error.Println("failed to check eibc client initialized", err) + return + } + oh := initconfig.NewOutputHandler(false) + + if isEibcClientInitialized { + pterm.Warning.Println("eibc client already initialized") + shouldOverwrite, err := oh.PromptOverwriteConfig(eibcHome) + if err != nil { + errorhandling.PrettifyErrorIfExists(err) + return + } + + if shouldOverwrite { + err = os.RemoveAll(eibcHome) + if err != nil { + errorhandling.PrettifyErrorIfExists(err) + return + } + // nolint:gofumpt + err = os.MkdirAll(eibcHome, 0o755) + if err != nil { + errorhandling.PrettifyErrorIfExists(err) + return + } + } else { + os.Exit(0) + } + } + c := GetInitCommand() err = bash.ExecCmd(c) @@ -40,9 +91,67 @@ func initCmd() *cobra.Command { err = ensureWhaleAccount() if err != nil { - log.Printf("failed to create whale account: %v\n", err) + pterm.Error.Printf("failed to create whale account: %v\n", err) return } + + eibcConfigPath := filepath.Join(eibcHome, "config.yaml") + data, err := os.ReadFile(eibcConfigPath) + if err != nil { + fmt.Printf("Error reading file: %v\n", err) + return // Assume this is in a function that returns an error + } + + // Parse the YAML + var node yaml.Node + err = yaml.Unmarshal(data, &node) + if err != nil { + fmt.Printf("Error parsing YAML: %v\n", err) + return + } + + // Get the actual content node (usually the first child of the document node) + contentNode := &node + if node.Kind == yaml.DocumentNode && len(node.Content) > 0 { + contentNode = node.Content[0] + } + + // Update the nested fields + err = yamlconfig.UpdateNestedYAML( + contentNode, + []string{"node_address"}, + rollerConfig.HubData.RPC_URL, + ) + if err != nil { + fmt.Printf("Error updating YAML: %v\n", err) + return + } + + err = yamlconfig.UpdateNestedYAML( + contentNode, + []string{"whale", "account_name"}, + consts.KeysIds.Eibc, + ) + if err != nil { + fmt.Printf("Error updating YAML: %v\n", err) + return + } + + // Marshal the updated YAML + updatedData, err := yaml.Marshal(&node) + if err != nil { + fmt.Printf("Error marshaling YAML: %v\n", err) + return + } + + // Write the updated YAML back to the original file + err = os.WriteFile(eibcConfigPath, updatedData, 0o644) + if err != nil { + fmt.Printf("Error writing file: %v\n", err) + return + } + + pterm.Info.Println("eibc config updated successfully") }, } return cmd diff --git a/cmd/eibc/utils.go b/cmd/eibc/utils.go index 5a4378d5..ee8aa879 100644 --- a/cmd/eibc/utils.go +++ b/cmd/eibc/utils.go @@ -6,6 +6,7 @@ import ( "os" "github.com/docker/docker/client" + "github.com/pterm/pterm" initconfig "github.com/dymensionxyz/roller/cmd/config/init" "github.com/dymensionxyz/roller/cmd/consts" @@ -19,28 +20,20 @@ func ensureWhaleAccount() error { home, _ := os.UserHomeDir() kc := utils.KeyConfig{ Dir: consts.ConfigDirName.Eibc, - ID: "client", + ID: consts.KeysIds.Eibc, ChainBinary: consts.Executables.Dymension, Type: "", } _, err := utils.GetAddressInfoBinary(kc, consts.Executables.Dymension) if err != nil { - fmt.Println("whale account not found in the keyring, creating it now") + pterm.Info.Println("whale account not found in the keyring, creating it now") addressInfo, err := initconfig.CreateAddressBinary(kc, home) if err != nil { return err } - whaleAddress := utils.SecretAddressData{ - AddressData: utils.AddressData{ - Name: addressInfo.Name, - Addr: addressInfo.Address, - }, - Mnemonic: addressInfo.Mnemonic, - } - - utils.PrintSecretAddressesWithTitle([]utils.SecretAddressData{whaleAddress}) + addressInfo.Print(utils.WithName(), utils.WithMnemonic()) } return nil diff --git a/utils/config/yamlconfig/yaml.go b/utils/config/yamlconfig/yaml.go new file mode 100644 index 00000000..f264c916 --- /dev/null +++ b/utils/config/yamlconfig/yaml.go @@ -0,0 +1,48 @@ +package yamlconfig + +import ( + "fmt" + + yaml "gopkg.in/yaml.v3" +) + +func UpdateNestedYAML(node *yaml.Node, path []string, value string) error { + if len(path) == 0 { + node.Value = value + return nil + } + + if node.Kind != yaml.MappingNode { + return fmt.Errorf("expected a mapping node, got %v", node.Kind) + } + + for i := 0; i < len(node.Content); i += 2 { + if node.Content[i].Value == path[0] { + return UpdateNestedYAML(node.Content[i+1], path[1:], value) + } + } + + return fmt.Errorf("path not found: %v", path[0]) +} + +func PrintYAMLStructure(node *yaml.Node, indent string) { + switch node.Kind { + case yaml.DocumentNode: + for _, n := range node.Content { + PrintYAMLStructure(n, indent) + } + case yaml.MappingNode: + fmt.Printf("%sMapping:\n", indent) + for i := 0; i < len(node.Content); i += 2 { + fmt.Printf("%s %s:\n", indent, node.Content[i].Value) + PrintYAMLStructure(node.Content[i+1], indent+" ") + } + case yaml.SequenceNode: + fmt.Printf("%sSequence:\n", indent) + for _, n := range node.Content { + PrintYAMLStructure(n, indent+" ") + } + case yaml.ScalarNode: + fmt.Printf("%sScalar: %s\n", indent, node.Value) + } +}