Skip to content

Commit a990d4f

Browse files
committed
feat: full interface for weave initia init
1 parent 77dd204 commit a990d4f

File tree

4 files changed

+263
-16
lines changed

4 files changed

+263
-16
lines changed

models/weaveinit/run_l1_node.go

+242-1
Original file line numberDiff line numberDiff line change
@@ -613,7 +613,12 @@ func (m *InitializingAppLoading) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
613613
m.Loading = loader
614614
if m.Loading.Completing {
615615
m.state.weave.PreviousResponse += styles.RenderPreviousResponse(styles.NoSeparator, "Initialization successful.", []string{}, "")
616-
return m, tea.Quit
616+
switch m.state.network {
617+
case string(Local):
618+
return m, tea.Quit
619+
case string(Mainnet), string(Testnet):
620+
return NewSyncMethodSelect(m.state), nil
621+
}
617622
}
618623
return m, cmd
619624
}
@@ -624,3 +629,239 @@ func (m *InitializingAppLoading) View() string {
624629
}
625630
return m.state.weave.PreviousResponse + m.Loading.View()
626631
}
632+
633+
type SyncMethodSelect struct {
634+
utils.Selector[SyncMethodOption]
635+
state *RunL1NodeState
636+
question string
637+
}
638+
639+
type SyncMethodOption string
640+
641+
const (
642+
Snapshot SyncMethodOption = "Snapshot"
643+
StateSync SyncMethodOption = "State Sync"
644+
)
645+
646+
func NewSyncMethodSelect(state *RunL1NodeState) *SyncMethodSelect {
647+
return &SyncMethodSelect{
648+
Selector: utils.Selector[SyncMethodOption]{
649+
Options: []SyncMethodOption{
650+
Snapshot,
651+
StateSync,
652+
},
653+
},
654+
state: state,
655+
question: "Please select a sync option",
656+
}
657+
}
658+
659+
func (m *SyncMethodSelect) GetQuestion() string {
660+
return m.question
661+
}
662+
663+
func (m *SyncMethodSelect) Init() tea.Cmd {
664+
return nil
665+
}
666+
667+
func (m *SyncMethodSelect) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
668+
selected, cmd := m.Select(msg)
669+
if selected != nil {
670+
m.state.syncMethod = string(*selected)
671+
m.state.weave.PreviousResponse += styles.RenderPreviousResponse(styles.ArrowSeparator, m.GetQuestion(), []string{""}, string(*selected))
672+
return NewExistingDataChecker(m.state), utils.DoTick()
673+
}
674+
675+
return m, cmd
676+
}
677+
678+
func (m *SyncMethodSelect) View() string {
679+
return m.state.weave.PreviousResponse + styles.RenderPrompt(
680+
m.GetQuestion(),
681+
[]string{""},
682+
styles.Question,
683+
) + m.Selector.View()
684+
}
685+
686+
type ExistingDataChecker struct {
687+
state *RunL1NodeState
688+
}
689+
690+
func NewExistingDataChecker(state *RunL1NodeState) *ExistingDataChecker {
691+
return &ExistingDataChecker{
692+
state: state,
693+
}
694+
}
695+
696+
func (m *ExistingDataChecker) Init() tea.Cmd {
697+
return utils.DoTick()
698+
}
699+
700+
func (m *ExistingDataChecker) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
701+
switch msg.(type) {
702+
case utils.TickMsg:
703+
homeDir, err := os.UserHomeDir()
704+
if err != nil {
705+
fmt.Printf("[error] Failed to get user home directory: %v\n", err)
706+
return m, tea.Quit
707+
}
708+
709+
initiaDataPath := filepath.Join(homeDir, utils.InitiaDataDirectory)
710+
if !utils.FileOrFolderExists(initiaDataPath) {
711+
m.state.existingData = false
712+
switch m.state.syncMethod {
713+
case string(Snapshot):
714+
return NewSnapshotEndpointInput(m.state), nil
715+
case string(StateSync):
716+
return NewStateSyncEndpointInput(m.state), nil
717+
}
718+
return m, tea.Quit
719+
} else {
720+
m.state.existingData = true
721+
return NewExistingDataReplaceSelect(m.state), nil
722+
}
723+
default:
724+
return m, nil
725+
}
726+
}
727+
728+
func (m *ExistingDataChecker) View() string {
729+
return m.state.weave.PreviousResponse + "Checking for existing Initia data..."
730+
}
731+
732+
type ExistingDataReplaceSelect struct {
733+
utils.Selector[ExistingDataReplaceOption]
734+
state *RunL1NodeState
735+
question string
736+
}
737+
738+
type ExistingDataReplaceOption string
739+
740+
const (
741+
UseCurrentData ExistingDataReplaceOption = "Use current one"
742+
ReplaceData ExistingDataReplaceOption = "Replace"
743+
)
744+
745+
func NewExistingDataReplaceSelect(state *RunL1NodeState) *ExistingDataReplaceSelect {
746+
return &ExistingDataReplaceSelect{
747+
Selector: utils.Selector[ExistingDataReplaceOption]{
748+
Options: []ExistingDataReplaceOption{
749+
UseCurrentData,
750+
ReplaceData,
751+
},
752+
},
753+
state: state,
754+
question: "Existing .initia/data detected. Would you like to use the current one or replace it",
755+
}
756+
}
757+
758+
func (m *ExistingDataReplaceSelect) GetQuestion() string {
759+
return m.question
760+
}
761+
762+
func (m *ExistingDataReplaceSelect) Init() tea.Cmd {
763+
return nil
764+
}
765+
766+
func (m *ExistingDataReplaceSelect) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
767+
selected, cmd := m.Select(msg)
768+
if selected != nil {
769+
m.state.weave.PreviousResponse += styles.RenderPreviousResponse(styles.ArrowSeparator, m.GetQuestion(), []string{".initia/data"}, string(*selected))
770+
switch *selected {
771+
case UseCurrentData:
772+
m.state.replaceExistingData = false
773+
return m, tea.Quit
774+
case ReplaceData:
775+
m.state.replaceExistingData = true
776+
switch m.state.syncMethod {
777+
case string(Snapshot):
778+
return NewSnapshotEndpointInput(m.state), nil
779+
case string(StateSync):
780+
return NewStateSyncEndpointInput(m.state), nil
781+
}
782+
}
783+
return m, tea.Quit
784+
}
785+
786+
return m, cmd
787+
}
788+
789+
func (m *ExistingDataReplaceSelect) View() string {
790+
return m.state.weave.PreviousResponse + styles.RenderPrompt(m.GetQuestion(), []string{".initia/data"}, styles.Question) + m.Selector.View()
791+
}
792+
793+
type SnapshotEndpointInput struct {
794+
utils.TextInput
795+
state *RunL1NodeState
796+
question string
797+
}
798+
799+
func NewSnapshotEndpointInput(state *RunL1NodeState) *SnapshotEndpointInput {
800+
return &SnapshotEndpointInput{
801+
TextInput: utils.NewTextInput(),
802+
state: state,
803+
question: "Please specify the snapshot url to download",
804+
}
805+
}
806+
807+
func (m *SnapshotEndpointInput) GetQuestion() string {
808+
return m.question
809+
}
810+
811+
func (m *SnapshotEndpointInput) Init() tea.Cmd {
812+
return nil
813+
}
814+
815+
func (m *SnapshotEndpointInput) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
816+
input, cmd, done := m.TextInput.Update(msg)
817+
if done {
818+
m.state.snapshotEndpoint = input.Text
819+
m.state.weave.PreviousResponse += styles.RenderPreviousResponse(styles.DotsSeparator, m.GetQuestion(), []string{"snapshot url"}, input.Text)
820+
// TODO: Continue
821+
return m, tea.Quit
822+
}
823+
m.TextInput = input
824+
return m, cmd
825+
}
826+
827+
func (m *SnapshotEndpointInput) View() string {
828+
return m.state.weave.PreviousResponse + styles.RenderPrompt(m.GetQuestion(), []string{"snapshot url"}, styles.Question) + m.TextInput.View()
829+
}
830+
831+
type StateSyncEndpointInput struct {
832+
utils.TextInput
833+
state *RunL1NodeState
834+
question string
835+
}
836+
837+
func NewStateSyncEndpointInput(state *RunL1NodeState) *StateSyncEndpointInput {
838+
return &StateSyncEndpointInput{
839+
TextInput: utils.NewTextInput(),
840+
state: state,
841+
question: "Please specify the state sync RPC server url",
842+
}
843+
}
844+
845+
func (m *StateSyncEndpointInput) GetQuestion() string {
846+
return m.question
847+
}
848+
849+
func (m *StateSyncEndpointInput) Init() tea.Cmd {
850+
return nil
851+
}
852+
853+
func (m *StateSyncEndpointInput) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
854+
input, cmd, done := m.TextInput.Update(msg)
855+
if done {
856+
m.state.stateSyncEndpoint = input.Text
857+
m.state.weave.PreviousResponse += styles.RenderPreviousResponse(styles.DotsSeparator, m.GetQuestion(), []string{"state sync RPC"}, input.Text)
858+
// TODO: Continue
859+
return m, tea.Quit
860+
}
861+
m.TextInput = input
862+
return m, cmd
863+
}
864+
865+
func (m *StateSyncEndpointInput) View() string {
866+
return m.state.weave.PreviousResponse + styles.RenderPrompt(m.GetQuestion(), []string{"state sync RPC"}, styles.Question) + m.TextInput.View()
867+
}

models/weaveinit/state.go

+19-14
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,23 @@ package weaveinit
33
import "github.com/initia-labs/weave/types"
44

55
type RunL1NodeState struct {
6-
weave types.WeaveState
7-
network string
8-
initiadVersion string
9-
chainId string
10-
moniker string
11-
existingApp bool
12-
replaceExistingApp bool
13-
minGasPrice string
14-
enableLCD bool
15-
enableGRPC bool
16-
seeds string
17-
persistentPeers string
18-
existingGenesis bool
19-
genesisEndpoint string
6+
weave types.WeaveState
7+
network string
8+
initiadVersion string
9+
chainId string
10+
moniker string
11+
existingApp bool
12+
replaceExistingApp bool
13+
minGasPrice string
14+
enableLCD bool
15+
enableGRPC bool
16+
seeds string
17+
persistentPeers string
18+
existingGenesis bool
19+
genesisEndpoint string
20+
existingData bool
21+
syncMethod string
22+
replaceExistingData bool
23+
snapshotEndpoint string
24+
stateSyncEndpoint string
2025
}

utils/constants.go

+1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ package utils
22

33
const (
44
InitiaConfigDirectory = ".initia/config"
5+
InitiaDataDirectory = ".initia/data"
56
)

utils/text_input.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func (ti TextInput) Update(msg tea.Msg) (TextInput, tea.Cmd, bool) {
3232
ti.Text = ti.Text[:ti.Cursor-1] + ti.Text[ti.Cursor:]
3333
ti.Cursor--
3434
}
35-
case tea.KeyRunes:
35+
case tea.KeyRunes, tea.KeySpace:
3636
ti.Text = ti.Text[:ti.Cursor] + string(msg.Runes) + ti.Text[ti.Cursor:]
3737
ti.Cursor += len(msg.Runes)
3838
case tea.KeyLeft:

0 commit comments

Comments
 (0)