diff --git a/cmd/gtk/main_window.go b/cmd/gtk/main_window.go
index ab0b689c7..b3322ee82 100644
--- a/cmd/gtk/main_window.go
+++ b/cmd/gtk/main_window.go
@@ -7,7 +7,6 @@ import (
"github.com/gotk3/gotk3/gtk"
"github.com/pactus-project/pactus/crypto"
- "github.com/pactus-project/pactus/util"
)
//go:embed assets/ui/main_window.ui
@@ -84,19 +83,19 @@ func (mw *mainWindow) OnTransactionTransfer() {
}
func (mw *mainWindow) onMenuItemActivateWebsite(_ *gtk.MenuItem) {
- if err := util.OpenURLInBrowser("https://pactus.org/"); err != nil {
+ if err := openURLInBrowser("https://pactus.org/"); err != nil {
fatalErrorCheck(err)
}
}
func (mw *mainWindow) onMenuItemActivateExplorer(_ *gtk.MenuItem) {
- if err := util.OpenURLInBrowser("https://pactusscan.com/"); err != nil {
+ if err := openURLInBrowser("https://pactusscan.com/"); err != nil {
fatalErrorCheck(err)
}
}
func (mw *mainWindow) onMenuItemActivateLearn(_ *gtk.MenuItem) {
- if err := util.OpenURLInBrowser("https://pactus.org/learn/"); err != nil {
+ if err := openURLInBrowser("https://pactus.org/learn/"); err != nil {
fatalErrorCheck(err)
}
}
diff --git a/cmd/gtk/startup_assistant.go b/cmd/gtk/startup_assistant.go
index ae89518f4..4c34e383e 100644
--- a/cmd/gtk/startup_assistant.go
+++ b/cmd/gtk/startup_assistant.go
@@ -15,6 +15,9 @@ import (
"github.com/pactus-project/pactus/wallet"
)
+type assistantFunc func(assistant *gtk.Assistant, content gtk.IWidget, name,
+ title, subject, desc string) *gtk.Widget
+
func setMargin(widget gtk.IWidget, top, bottom, start, end int) {
widget.ToWidget().SetMarginTop(top)
widget.ToWidget().SetMarginBottom(bottom)
@@ -24,8 +27,202 @@ func setMargin(widget gtk.IWidget, top, bottom, start, end int) {
func startupAssistant(workingDir string, chain genesis.ChainType) bool {
successful := false
- createPage := func(assistant *gtk.Assistant, content gtk.IWidget, name,
- title, subject, desc string) *gtk.Widget {
+ assistant, err := gtk.AssistantNew()
+ fatalErrorCheck(err)
+
+ assistant.SetDefaultSize(600, 400)
+ assistant.SetTitle("Pactus - Init Wizard")
+
+ assistFunc := pageAssistant()
+
+ // --- page_mode
+ mode, restoreRadio, pageModeName := pageMode(assistant, assistFunc)
+
+ // --- page_seed_generate
+ seedGenerate, textViewSeed, pageSeedGenerateName := pageSeedGenerate(assistant, assistFunc)
+
+ // --- page_seed_confirm
+ seedConfirm, pageSeedConfirmName := pageSeedConfirm(assistant, assistFunc, textViewSeed)
+
+ // -- page_seed_restore
+ seedRestore, textViewRestoreSeed, pageSeedRestoreName := pageSeedRestore(assistant, assistFunc)
+
+ // --- page_password
+ password, entryPassword, pagePasswordName := pagePassword(assistant, assistFunc)
+
+ // --- page_num_validators
+ numValidators, lsNumValidators, comboNumValidators, pageNumValidatorsName := pageNumValidators(assistant, assistFunc)
+
+ // --- page_final
+ final, textViewNodeInfo, pageFinalName := pageFinal(assistant, assistFunc)
+
+ assistant.Connect("cancel", func() {
+ assistant.Close()
+ assistant.Destroy()
+ gtk.MainQuit()
+ })
+ assistant.Connect("close", func() {
+ assistant.Close()
+ assistant.Destroy()
+ gtk.MainQuit()
+ })
+
+ assistant.SetPageType(mode, gtk.ASSISTANT_PAGE_INTRO) // page 0
+ assistant.SetPageType(seedGenerate, gtk.ASSISTANT_PAGE_CONTENT) // page 1
+ assistant.SetPageType(seedConfirm, gtk.ASSISTANT_PAGE_CONTENT) // page 2
+ assistant.SetPageType(seedRestore, gtk.ASSISTANT_PAGE_CONTENT) // page 3
+ assistant.SetPageType(password, gtk.ASSISTANT_PAGE_CONTENT) // page 4
+ assistant.SetPageType(numValidators, gtk.ASSISTANT_PAGE_CONTENT) // page 5
+ assistant.SetPageType(final, gtk.ASSISTANT_PAGE_SUMMARY) // page 6
+
+ mnemonic := ""
+ prevPageIndex := -1
+ prevPageAdjust := 0
+ assistant.Connect("prepare", func(assistant *gtk.Assistant, page *gtk.Widget) {
+ isRestoreMode := restoreRadio.GetActive()
+ curPageName, err := page.GetName()
+ curPageIndex := assistant.GetCurrentPage()
+ fatalErrorCheck(err)
+
+ isForward := true
+ if curPageIndex > 0 && curPageIndex < prevPageIndex {
+ isForward = false
+ }
+
+ log.Printf("%v (restore: %v, prev: %v, cur: %v)\n",
+ curPageName, isRestoreMode, prevPageIndex, curPageIndex)
+ switch curPageName {
+ case pageModeName:
+ {
+ assistantPageComplete(assistant, mode, true)
+ }
+
+ case pageSeedGenerateName:
+ {
+ if isRestoreMode {
+ if isForward {
+ // forward
+ log.Printf("jumping forward from seedGenerate page")
+ assistant.NextPage()
+ prevPageAdjust = 1
+ } else {
+ // backward
+ log.Printf("jumping backward from seedGenerate page")
+ assistant.PreviousPage()
+ prevPageAdjust = -1
+ }
+ assistantPageComplete(assistant, seedGenerate, false)
+ } else {
+ mnemonic = wallet.GenerateMnemonic(128)
+ setTextViewContent(textViewSeed, mnemonic)
+ assistantPageComplete(assistant, seedGenerate, true)
+ }
+ }
+ case pageSeedConfirmName:
+ {
+ if isRestoreMode {
+ if isForward {
+ // forward
+ log.Printf("jumping forward from seedConfirm page")
+ assistant.NextPage()
+ prevPageAdjust = 1
+ } else {
+ // backward
+ log.Printf("jumping backward from seedConfirm page")
+ assistant.PreviousPage()
+ prevPageAdjust = -1
+ }
+ assistantPageComplete(assistant, seedConfirm, false)
+ } else {
+ assistantPageComplete(assistant, seedConfirm, false)
+ }
+ }
+ case pageSeedRestoreName:
+ {
+ if !isRestoreMode {
+ if isForward {
+ // forward
+ log.Printf("jumping forward from seedRestore page")
+ assistant.NextPage()
+ prevPageAdjust = 1
+ } else {
+ // backward
+ log.Printf("jumping backward from seedRestore page")
+ assistant.PreviousPage()
+ prevPageAdjust = -1
+ }
+ assistantPageComplete(assistant, seedConfirm, false)
+ } else {
+ assistantPageComplete(assistant, seedRestore, true)
+ }
+ }
+ case pagePasswordName:
+ {
+ if isRestoreMode {
+ mnemonic = getTextViewContent(textViewRestoreSeed)
+
+ if err := wallet.CheckMnemonic(mnemonic); err != nil {
+ showErrorDialog(assistant, "mnemonic is invalid")
+ assistant.PreviousPage()
+ }
+ }
+ assistantPageComplete(assistant, password, true)
+ }
+ case pageNumValidatorsName:
+ {
+ assistantPageComplete(assistant, numValidators, true)
+ }
+
+ case pageFinalName:
+ {
+ iter, err := comboNumValidators.GetActiveIter()
+ fatalErrorCheck(err)
+
+ val, err := lsNumValidators.GetValue(iter, 0)
+ fatalErrorCheck(err)
+
+ valueInterface, err := val.GoValue()
+ fatalErrorCheck(err)
+
+ numValidators := valueInterface.(int)
+
+ fmt.Println("number of validators:", numValidators)
+
+ walletPassword, err := entryPassword.GetText()
+ fatalErrorCheck(err)
+
+ validatorAddrs, rewardAddrs, err := cmd.CreateNode(numValidators, chain, workingDir, mnemonic, walletPassword)
+ fatalErrorCheck(err)
+
+ // Done! showing the node information
+ successful = true
+ nodeInfo := fmt.Sprintf("Working directory: %s\n", workingDir)
+ nodeInfo += fmt.Sprintf("Network: %s\n", chain.String())
+ nodeInfo += "\nValidator addresses:\n"
+ for i, addr := range validatorAddrs {
+ nodeInfo += fmt.Sprintf("%v- %s\n", i+1, addr)
+ }
+
+ nodeInfo += "\nReward addresses:\n"
+ for i, addr := range rewardAddrs {
+ nodeInfo += fmt.Sprintf("%v- %s\n", i+1, addr)
+ }
+
+ setTextViewContent(textViewNodeInfo, nodeInfo)
+ }
+ }
+ prevPageIndex = curPageIndex + prevPageAdjust
+ })
+
+ assistant.SetModal(true)
+ assistant.ShowAll()
+
+ gtk.Main()
+ return successful
+}
+
+func pageAssistant() assistantFunc {
+ return func(assistant *gtk.Assistant, content gtk.IWidget, name, title, subject, desc string) *gtk.Widget {
page, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 20)
fatalErrorCheck(err)
@@ -53,58 +250,47 @@ func startupAssistant(workingDir string, chain genesis.ChainType) bool {
box.Add(frame)
box.Add(labelDesc)
page.Add(box)
-
page.SetName(name)
assistant.AppendPage(page)
assistant.SetPageTitle(page, title)
return page.ToWidget()
}
+}
- assistant, err := gtk.AssistantNew()
- fatalErrorCheck(err)
-
- assistant.SetDefaultSize(600, 400)
- assistant.SetTitle("Pactus - Init Wizard")
-
- var pageMode *gtk.Widget
- var pagePassword *gtk.Widget
- var pageSeed *gtk.Widget
- var pageSeedConfirm *gtk.Widget
- var pageNumValidators *gtk.Widget
- var pageFinal *gtk.Widget
-
- // --- PageMode
+func pageMode(assistant *gtk.Assistant, assistFunc assistantFunc) (*gtk.Widget, *gtk.RadioButton, string) {
+ var mode *gtk.Widget
newWalletRadio, err := gtk.RadioButtonNewWithLabel(nil, "Create a new wallet from the scratch")
fatalErrorCheck(err)
- recoverWalletRadio, err := gtk.RadioButtonNewWithLabelFromWidget(newWalletRadio,
+ restoreWalletRadio, err := gtk.RadioButtonNewWithLabelFromWidget(newWalletRadio,
"Restore a wallet from the seed phrase")
fatalErrorCheck(err)
- recoverWalletRadio.SetSensitive(false)
-
radioBox, err := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, 0)
fatalErrorCheck(err)
radioBox.Add(newWalletRadio)
setMargin(newWalletRadio, 6, 6, 6, 6)
- radioBox.Add(recoverWalletRadio)
- setMargin(recoverWalletRadio, 6, 6, 6, 6)
+ radioBox.Add(restoreWalletRadio)
+ setMargin(restoreWalletRadio, 6, 6, 6, 6)
pageModeName := "page_mode"
pageModeTitle := "Initialize mode"
pageModeSubject := "How to create your wallet?"
pageModeDesc := "If you are running the node for the first time, choose the first option."
- pageMode = createPage(
+ mode = assistFunc(
assistant,
radioBox,
pageModeName,
pageModeTitle,
pageModeSubject,
pageModeDesc)
+ return mode, restoreWalletRadio, pageModeName
+}
- // --- pageSeed
+func pageSeedGenerate(assistant *gtk.Assistant, assistFunc assistantFunc) (*gtk.Widget, *gtk.TextView, string) {
+ var pageWidget *gtk.Widget
textViewSeed, err := gtk.TextViewNew()
fatalErrorCheck(err)
@@ -114,7 +300,7 @@ func startupAssistant(workingDir string, chain genesis.ChainType) bool {
textViewSeed.SetMonospace(true)
textViewSeed.SetSizeRequest(0, 80)
- pageSeedName := "page_seed"
+ pageSeedName := "page_seed_generate"
pageSeedTitle := "Wallet seed"
pageSeedSubject := "Your wallet generation seed is:"
pageSeedDesc := `Please write these 12 words on paper.
@@ -124,15 +310,45 @@ This seed will allow you to recover your wallet in case of computer failure.
- Never type it on a website.
- Do not store it electronically.`
- pageSeed = createPage(
+ pageWidget = assistFunc(
assistant,
textViewSeed,
pageSeedName,
pageSeedTitle,
pageSeedSubject,
pageSeedDesc)
+ return pageWidget, textViewSeed, pageSeedName
+}
+
+func pageSeedRestore(assistant *gtk.Assistant, assistFunc assistantFunc) (*gtk.Widget, *gtk.TextView, string) {
+ var pageWidget *gtk.Widget
+ textViewRestoreSeed, err := gtk.TextViewNew()
+ fatalErrorCheck(err)
+
+ setMargin(textViewRestoreSeed, 6, 6, 6, 6)
+ textViewRestoreSeed.SetWrapMode(gtk.WRAP_WORD)
+ textViewRestoreSeed.SetEditable(true)
+ textViewRestoreSeed.SetMonospace(true)
+ textViewRestoreSeed.SetSizeRequest(0, 80)
+
+ pageSeedName := "page_seed_restore"
+ pageSeedTitle := "Wallet seed restore"
+ pageSeedSubject := "Enter your wallet seed:"
+ pageSeedDesc := "Please enter your 12 words mnemonics backup to restore your wallet."
+
+ pageWidget = assistFunc(
+ assistant,
+ textViewRestoreSeed,
+ pageSeedName,
+ pageSeedTitle,
+ pageSeedSubject,
+ pageSeedDesc)
+ return pageWidget, textViewRestoreSeed, pageSeedName
+}
- // --- pageSeedConfirm
+func pageSeedConfirm(assistant *gtk.Assistant, assistFunc assistantFunc,
+ textViewSeed *gtk.TextView) (*gtk.Widget, string) {
+ pageWidget := new(gtk.Widget)
textViewConfirmSeed, err := gtk.TextViewNew()
fatalErrorCheck(err)
@@ -157,9 +373,9 @@ This seed will allow you to recover your wallet in case of computer failure.
mnemonic2 = space.ReplaceAllString(mnemonic2, " ")
mnemonic2 = strings.TrimSpace(mnemonic2)
if mnemonic1 == mnemonic2 {
- assistant.SetPageComplete(pageSeedConfirm, true)
+ assistantPageComplete(assistant, pageWidget, true)
} else {
- assistant.SetPageComplete(pageSeedConfirm, false)
+ assistantPageComplete(assistant, pageWidget, false)
}
})
@@ -169,15 +385,18 @@ This seed will allow you to recover your wallet in case of computer failure.
pageSeedConfirmDesc := `Your seed is important!
To make sure that you have properly saved your seed, please retype it here.`
- pageSeedConfirm = createPage(
+ pageWidget = assistFunc(
assistant,
textViewConfirmSeed,
pageSeedConfirmName,
pageSeedConfirmTitle,
pageSeedConfirmSubject,
pageSeedConfirmDesc)
+ return pageWidget, pageSeedConfirmName
+}
- // --- PagePassword
+func pagePassword(assistant *gtk.Assistant, assistFunc assistantFunc) (*gtk.Widget, *gtk.Entry, string) {
+ pageWidget := new(gtk.Widget)
entryPassword, err := gtk.EntryNew()
fatalErrorCheck(err)
@@ -216,9 +435,9 @@ To make sure that you have properly saved your seed, please retype it here.`
fatalErrorCheck(err)
if pass1 == pass2 {
- assistant.SetPageComplete(pagePassword, true)
+ assistantPageComplete(assistant, pageWidget, true)
} else {
- assistant.SetPageComplete(pagePassword, false)
+ assistantPageComplete(assistant, pageWidget, false)
}
}
entryPassword.Connect("changed", func(entry *gtk.Entry) {
@@ -234,15 +453,19 @@ To make sure that you have properly saved your seed, please retype it here.`
pagePasswordSubject := "Enter password for your wallet:"
pagePsswrdDesc := "Please choose a strong password for your wallet."
- pagePassword = createPage(
+ pageWidget = assistFunc(
assistant,
grid,
pagePasswordName,
pagePasswordTitle,
pagePasswordSubject,
pagePsswrdDesc)
+ return pageWidget, entryPassword, pagePasswordName
+}
- // --- pageNumValidators
+func pageNumValidators(assistant *gtk.Assistant,
+ assistFunc assistantFunc) (*gtk.Widget, *gtk.ListStore, *gtk.ComboBox, string) {
+ var pageWidget *gtk.Widget
lsNumValidators, err := gtk.ListStoreNew(glib.TYPE_INT)
fatalErrorCheck(err)
@@ -270,7 +493,7 @@ To make sure that you have properly saved your seed, please retype it here.`
setMargin(labelNumValidators, 6, 6, 6, 6)
setMargin(comboNumValidators, 6, 6, 6, 6)
- grid, err = gtk.GridNew()
+ grid, err := gtk.GridNew()
fatalErrorCheck(err)
grid.Add(labelNumValidators)
@@ -283,15 +506,18 @@ To make sure that you have properly saved your seed, please retype it here.`
You can define validators based on the amount of coins you want to stake.
For more information, look here`
- pageNumValidators = createPage(
+ pageWidget = assistFunc(
assistant,
grid,
pageNumValidatorsName,
pageNumValidatorsTitle,
pageNumValidatorsSubject,
pageNumValidatorsDesc)
+ return pageWidget, lsNumValidators, comboNumValidators, pageNumValidatorsName
+}
- // --- pageFinal
+func pageFinal(assistant *gtk.Assistant, assistFunc assistantFunc) (*gtk.Widget, *gtk.TextView, string) {
+ var pageWidget *gtk.Widget
textViewNodeInfo, err := gtk.TextViewNew()
fatalErrorCheck(err)
@@ -312,109 +538,17 @@ For more information, look