From 1804fd3a8ebaf1810337d9f9e73a45c2bcede34f Mon Sep 17 00:00:00 2001 From: jemiluv8 Date: Tue, 24 Oct 2023 23:53:42 +0000 Subject: [PATCH] feat: create new validator address (CLI and GUI) (#757) --- .../assets/ui/dialog_wallet_create_address.ui | 136 ++++++++++++++++++ cmd/gtk/dialog_wallet_create_address.go | 73 ++++++++++ cmd/gtk/model_wallet.go | 34 ----- cmd/gtk/widget_wallet.go | 9 +- cmd/wallet/address.go | 59 +++++--- cmd/wallet/create.go | 8 +- cmd/wallet/history.go | 10 +- cmd/wallet/recover.go | 6 +- wallet/client.go | 5 + 9 files changed, 266 insertions(+), 74 deletions(-) create mode 100644 cmd/gtk/assets/ui/dialog_wallet_create_address.ui create mode 100644 cmd/gtk/dialog_wallet_create_address.go diff --git a/cmd/gtk/assets/ui/dialog_wallet_create_address.ui b/cmd/gtk/assets/ui/dialog_wallet_create_address.ui new file mode 100644 index 000000000..1964b2bad --- /dev/null +++ b/cmd/gtk/assets/ui/dialog_wallet_create_address.ui @@ -0,0 +1,136 @@ + + + + + + False + New address + 320 + dialog + + + False + 8 + 8 + 4 + 4 + vertical + 2 + + + False + end + + + _Cancel + True + True + False + False + True + True + + + + + True + True + 0 + + + + + _Ok + True + True + False + True + True + True + True + True + + + + + True + True + 1 + + + + + False + False + 0 + + + + + + True + False + 8 + 8 + + + True + False + start + Label: + + + 0 + 0 + + + + + True + True + True + 24 + + + 1 + 0 + + + + + True + False + start + Type: + + + 0 + 1 + + + + + True + False + + + 1 + 1 + + + + + True + True + 8 + 1 + + + + + + id_button_cancel + id_button_ok + + + diff --git a/cmd/gtk/dialog_wallet_create_address.go b/cmd/gtk/dialog_wallet_create_address.go new file mode 100644 index 000000000..f708b93f3 --- /dev/null +++ b/cmd/gtk/dialog_wallet_create_address.go @@ -0,0 +1,73 @@ +//go:build gtk + +package main + +import ( + _ "embed" + "fmt" + + "github.com/gotk3/gotk3/gtk" + + "github.com/pactus-project/pactus/wallet" +) + +//go:embed assets/ui/dialog_wallet_create_address.ui +var uiWalletCreateAddressDialog []byte + +func createAddress(ww *widgetWallet) { + builder, err := gtk.BuilderNewFromString(string(uiWalletCreateAddressDialog)) + fatalErrorCheck(err) + + dlg := getDialogObj(builder, "id_dialog_wallet_create_address") + addressLabel := getEntryObj(builder, "id_entry_account_label") + + addressTypeCombo := getComboBoxTextObj(builder, "id_combo_address_type") + addressTypeCombo.Append(wallet.AddressTypeBLSAccount, "Account") + addressTypeCombo.Append(wallet.AddressTypeValidator, "Validator") + + addressTypeCombo.SetActive(0) + + getButtonObj(builder, "id_button_ok").SetImage(OkIcon()) + getButtonObj(builder, "id_button_cancel").SetImage(CancelIcon()) + + onOk := func() { + walletAddressLabel, err := addressLabel.GetText() + fatalErrorCheck(err) + + walletAddressType := addressTypeCombo.GetActiveID() + fatalErrorCheck(err) + + if walletAddressType == wallet.AddressTypeBLSAccount { + _, err = ww.model.wallet.NewBLSAccountAddress(walletAddressLabel) + } else if walletAddressType == wallet.AddressTypeValidator { + _, err = ww.model.wallet.NewValidatorAddress(walletAddressLabel) + } else { + err = fmt.Errorf("invalid address type '%s'", walletAddressType) + } + + errorCheck(err) + + err = ww.model.wallet.Save() + errorCheck(err) + + ww.model.rebuildModel() + + dlg.Close() + } + + onCancel := func() { + dlg.Close() + } + + // Map the handlers to callback functions, and connect the signals + // to the Builder. + signals := map[string]interface{}{ + "on_ok": onOk, + "on_cancel": onCancel, + } + builder.ConnectSignals(signals) + + dlg.SetModal(true) + + dlg.Run() +} diff --git a/cmd/gtk/model_wallet.go b/cmd/gtk/model_wallet.go index d87f4b653..db44c8cf1 100644 --- a/cmd/gtk/model_wallet.go +++ b/cmd/gtk/model_wallet.go @@ -84,37 +84,3 @@ func (model *walletModel) rebuildModel() { }) }() } - -func (model *walletModel) createAddress() error { - address, err := model.wallet.NewBLSAccountAddress("") - if err != nil { - return err - } - - iter := model.listStore.Append() - err = model.listStore.Set(iter, - []int{ - IDAddressesColumnNo, - IDAddressesColumnAddress, - IDAddressesColumnLabel, - IDAddressesColumnBalance, - IDAddressesColumnStake, - }, - []interface{}{ - fmt.Sprintf("%v", model.wallet.AddressCount()+1), - address, - "", - "0", - "0", - }) - if err != nil { - return err - } - - err = model.wallet.Save() - if err != nil { - return err - } - - return nil -} diff --git a/cmd/gtk/widget_wallet.go b/cmd/gtk/widget_wallet.go index 6bb07efaa..655ca17e2 100644 --- a/cmd/gtk/widget_wallet.go +++ b/cmd/gtk/widget_wallet.go @@ -147,15 +147,14 @@ func buildWidgetWallet(model *walletModel) (*widgetWallet, error) { return w, nil } -func (ww *widgetWallet) onNewAddress() { - err := ww.model.createAddress() - errorCheck(err) -} - func (ww *widgetWallet) onChangePassword() { changePassword(ww.model.wallet) } +func (ww *widgetWallet) onNewAddress() { + createAddress(ww) +} + func (ww *widgetWallet) onShowSeed() { password, ok := getWalletPassword(ww.model.wallet) if !ok { diff --git a/cmd/wallet/address.go b/cmd/wallet/address.go index a9568bcad..c93e211f1 100644 --- a/cmd/wallet/address.go +++ b/cmd/wallet/address.go @@ -6,6 +6,7 @@ import ( "github.com/pactus-project/pactus/cmd" "github.com/pactus-project/pactus/crypto/bls" "github.com/pactus-project/pactus/util" + "github.com/pactus-project/pactus/wallet" "github.com/spf13/cobra" ) @@ -41,20 +42,20 @@ func buildAllAddressesCmd(parentCmd *cobra.Command) { false, "Display the validator stake for each address") allAddressCmd.Run = func(_ *cobra.Command, _ []string) { - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) cmd.PrintLine() - for i, info := range wallet.AddressInfos() { + for i, info := range wlt.AddressInfos() { line := fmt.Sprintf("%v- %s\t", i+1, info.Address) if *balanceOpt { - balance, _ := wallet.Balance(info.Address) + balance, _ := wlt.Balance(info.Address) line += fmt.Sprintf("%v\t", util.ChangeToCoin(balance)) } if *stakeOpt { - stake, _ := wallet.Stake(info.Address) + stake, _ := wlt.Stake(info.Address) line += fmt.Sprintf("%v\t", util.ChangeToCoin(stake)) } @@ -76,15 +77,27 @@ func buildNewAddressCmd(parentCmd *cobra.Command) { } parentCmd.AddCommand(newAddressCmd) + addressType := newAddressCmd.Flags().String("type", + wallet.AddressTypeBLSAccount, "the type of address: bls_account or validator") + newAddressCmd.Run = func(_ *cobra.Command, _ []string) { + var addr string + var err error + label := cmd.PromptInput("Label") - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - addr, err := wallet.NewBLSAccountAddress(label) + if *addressType == wallet.AddressTypeBLSAccount { + addr, err = wlt.NewBLSAccountAddress(label) + } else if *addressType == wallet.AddressTypeValidator { + addr, err = wlt.NewValidatorAddress(label) + } else { + err = fmt.Errorf("invalid address type '%s'", *addressType) + } cmd.FatalErrorCheck(err) - err = wallet.Save() + err = wlt.Save() cmd.FatalErrorCheck(err) cmd.PrintLine() @@ -104,14 +117,14 @@ func buildBalanceCmd(parentCmd *cobra.Command) { balanceCmd.Run = func(_ *cobra.Command, args []string) { addr := args[0] - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) cmd.PrintLine() - balance, err := wallet.Balance(addr) + balance, err := wlt.Balance(addr) cmd.FatalErrorCheck(err) - stake, err := wallet.Stake(addr) + stake, err := wlt.Stake(addr) cmd.FatalErrorCheck(err) cmd.PrintInfoMsgf("balance: %v\tstake: %v", @@ -133,11 +146,11 @@ func buildPrivateKeyCmd(parentCmd *cobra.Command) { privateKeyCmd.Run = func(_ *cobra.Command, args []string) { addr := args[0] - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - password := getPassword(wallet, *passOpt) - prv, err := wallet.PrivateKey(password, addr) + password := getPassword(wlt, *passOpt) + prv, err := wlt.PrivateKey(password, addr) cmd.FatalErrorCheck(err) cmd.PrintLine() @@ -157,10 +170,10 @@ func buildPublicKeyCmd(parentCmd *cobra.Command) { publicKeyCmd.Run = func(_ *cobra.Command, args []string) { addr := args[0] - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - info := wallet.AddressInfo(addr) + info := wlt.AddressInfo(addr) if info == nil { cmd.PrintErrorMsgf("Address not found") return @@ -187,17 +200,17 @@ func buildImportPrivateKeyCmd(parentCmd *cobra.Command) { importPrivateKeyCmd.Run = func(_ *cobra.Command, _ []string) { prvStr := cmd.PromptInput("Private Key") - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) prv, err := bls.PrivateKeyFromString(prvStr) cmd.FatalErrorCheck(err) - password := getPassword(wallet, *passOpt) - err = wallet.ImportPrivateKey(password, prv) + password := getPassword(wlt, *passOpt) + err = wlt.ImportPrivateKey(password, prv) cmd.FatalErrorCheck(err) - err = wallet.Save() + err = wlt.Save() cmd.FatalErrorCheck(err) cmd.PrintLine() @@ -217,16 +230,16 @@ func buildSetLabelCmd(parentCmd *cobra.Command) { setLabelCmd.Run = func(c *cobra.Command, args []string) { addr := args[0] - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - oldLabel := wallet.Label(addr) + oldLabel := wlt.Label(addr) newLabel := cmd.PromptInputWithSuggestion("Label", oldLabel) - err = wallet.SetLabel(addr, newLabel) + err = wlt.SetLabel(addr, newLabel) cmd.FatalErrorCheck(err) - err = wallet.Save() + err = wlt.Save() cmd.FatalErrorCheck(err) cmd.PrintLine() diff --git a/cmd/wallet/create.go b/cmd/wallet/create.go index f5b740cff..8ce6b6c18 100644 --- a/cmd/wallet/create.go +++ b/cmd/wallet/create.go @@ -53,16 +53,16 @@ func buildChangePasswordCmd(parentCmd *cobra.Command) { passOpt := addPasswordOption(changePasswordCmd) changePasswordCmd.Run = func(_ *cobra.Command, _ []string) { - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - oldPassword := getPassword(wallet, *passOpt) + oldPassword := getPassword(wlt, *passOpt) newPassword := cmd.PromptPassword("New Password", true) - err = wallet.UpdatePassword(oldPassword, newPassword) + err = wlt.UpdatePassword(oldPassword, newPassword) cmd.FatalErrorCheck(err) - err = wallet.Save() + err = wlt.Save() cmd.FatalErrorCheck(err) cmd.PrintLine() diff --git a/cmd/wallet/history.go b/cmd/wallet/history.go index 78662f3da..aaa27b961 100644 --- a/cmd/wallet/history.go +++ b/cmd/wallet/history.go @@ -31,16 +31,16 @@ func buildAddToHistoryCmd(parentCmd *cobra.Command) { addToHistoryCmd.Run = func(_ *cobra.Command, args []string) { txID := args[0] - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) id, err := hash.FromString(txID) cmd.FatalErrorCheck(err) - err = wallet.AddTransaction(id) + err = wlt.AddTransaction(id) cmd.FatalErrorCheck(err) - err = wallet.Save() + err = wlt.Save() cmd.FatalErrorCheck(err) cmd.PrintInfoMsgf("Transaction successfully added to the wallet.") @@ -59,10 +59,10 @@ func buildShowHistoryCmd(parentCmd *cobra.Command) { showHistoryCmd.Run = func(_ *cobra.Command, args []string) { addr := args[0] - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - history := wallet.GetHistory(addr) + history := wlt.GetHistory(addr) for i, h := range history { if h.Time != nil { cmd.PrintInfoMsgf("%d %v %v %v %s\t%v", diff --git a/cmd/wallet/recover.go b/cmd/wallet/recover.go index 0c2cf31a5..98359ad1e 100644 --- a/cmd/wallet/recover.go +++ b/cmd/wallet/recover.go @@ -51,11 +51,11 @@ func buildGetSeedCmd(parentCmd *cobra.Command) { passOpt := addPasswordOption(getSeedCmd) getSeedCmd.Run = func(_ *cobra.Command, _ []string) { - wallet, err := openWallet() + wlt, err := openWallet() cmd.FatalErrorCheck(err) - password := getPassword(wallet, *passOpt) - mnemonic, err := wallet.Mnemonic(password) + password := getPassword(wlt, *passOpt) + mnemonic, err := wlt.Mnemonic(password) cmd.FatalErrorCheck(err) cmd.PrintLine() diff --git a/wallet/client.go b/wallet/client.go index e7e6c8480..886f3858d 100644 --- a/wallet/client.go +++ b/wallet/client.go @@ -12,6 +12,11 @@ import ( "google.golang.org/grpc/credentials/insecure" ) +const ( + AddressTypeBLSAccount string = "bls_account" + AddressTypeValidator string = "validator" +) + type grpcClient struct { blockchainClient pactus.BlockchainClient transactionClient pactus.TransactionClient