diff --git a/changelog.md b/changelog.md index 0b8a922ba7..77093639b9 100644 --- a/changelog.md +++ b/changelog.md @@ -6,6 +6,12 @@ # Changelog +## Unreleased + +### Features + +- [#2955](https://github.com/ignite/cli/pull/2955/) Add `ignite network request add-account` command. + ## [`v0.25.0`](https://github.com/ignite/cli/releases/tag/v0.25.0) ### Features diff --git a/ignite/cmd/network_request.go b/ignite/cmd/network_request.go index 7249c9a216..49e37b9c02 100644 --- a/ignite/cmd/network_request.go +++ b/ignite/cmd/network_request.go @@ -16,6 +16,7 @@ func NewNetworkRequest() *cobra.Command { NewNetworkRequestApprove(), NewNetworkRequestReject(), NewNetworkRequestVerify(), + NewNetworkRequestAddAccount(), ) return c diff --git a/ignite/cmd/network_request_add_account.go b/ignite/cmd/network_request_add_account.go new file mode 100644 index 0000000000..aca9ec897e --- /dev/null +++ b/ignite/cmd/network_request_add_account.go @@ -0,0 +1,90 @@ +package ignitecmd + +import ( + "errors" + "fmt" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/spf13/cobra" + + "github.com/ignite/cli/ignite/pkg/cliui" + "github.com/ignite/cli/ignite/services/network" + "github.com/ignite/cli/ignite/services/network/networkchain" +) + +// NewNetworkRequestAddAccount creates a new command to send add account request +func NewNetworkRequestAddAccount() *cobra.Command { + c := &cobra.Command{ + Use: "add-account [launch-id] [address] [coins]", + Short: "Send request to add account", + RunE: networkRequestAddAccountHandler, + Args: cobra.RangeArgs(2, 3), + } + + flagSetClearCache(c) + c.Flags().AddFlagSet(flagNetworkFrom()) + c.Flags().AddFlagSet(flagSetHome()) + c.Flags().AddFlagSet(flagSetKeyringBackend()) + c.Flags().AddFlagSet(flagSetKeyringDir()) + return c +} + +func networkRequestAddAccountHandler(cmd *cobra.Command, args []string) error { + session := cliui.New(cliui.StartSpinner()) + defer session.End() + + nb, err := newNetworkBuilder(cmd, CollectEvents(session.EventBus())) + if err != nil { + return err + } + + // parse launch ID + launchID, err := network.ParseID(args[0]) + if err != nil { + return err + } + + address := args[1] + + n, err := nb.Network() + if err != nil { + return err + } + + chainLaunch, err := n.ChainLaunch(cmd.Context(), launchID) + if err != nil { + return err + } + + c, err := nb.Chain(networkchain.SourceLaunch(chainLaunch)) + if err != nil { + return err + } + + var balance sdk.Coins + if c.IsAccountBalanceFixed() { + balance = c.AccountBalance() + if len(args) == 3 { + return fmt.Errorf( + "balance can't be provided, balance has been set by coordinator to %s", + balance.String(), + ) + } + } else { + if len(args) < 3 { + return errors.New("account balance expected") + } + balanceStr := args[2] + balance, err = sdk.ParseCoinsNormalized(balanceStr) + if err != nil { + return err + } + } + + return n.SendAccountRequest( + cmd.Context(), + launchID, + address, + balance, + ) +} diff --git a/ignite/services/network/join.go b/ignite/services/network/join.go index d0c528a4a3..7db0af07b8 100644 --- a/ignite/services/network/join.go +++ b/ignite/services/network/join.go @@ -7,6 +7,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" launchtypes "github.com/tendermint/spn/x/launch/types" + "github.com/ignite/cli/ignite/pkg/cliui/icons" "github.com/ignite/cli/ignite/pkg/cosmosutil" "github.com/ignite/cli/ignite/pkg/events" "github.com/ignite/cli/ignite/pkg/xurl" @@ -85,16 +86,75 @@ func (n Network) Join( } if !o.accountAmount.IsZero() { - if err := n.sendAccountRequest(ctx, launchID, accountAddress, o.accountAmount); err != nil { + if err := n.SendAccountRequest(ctx, launchID, accountAddress, o.accountAmount); err != nil { return err } } - return n.sendValidatorRequest(ctx, launchID, peer, accountAddress, gentx, gentxInfo) + return n.SendValidatorRequest(ctx, launchID, peer, accountAddress, gentx, gentxInfo) } -// sendValidatorRequest creates the RequestAddValidator message into the SPN -func (n Network) sendValidatorRequest( +func (n Network) SendAccountRequestForCoordinator(ctx context.Context, launchID uint64, amount sdk.Coins) error { + addr, err := n.account.Address(networktypes.SPN) + if err != nil { + return err + } + + return n.SendAccountRequest(ctx, launchID, addr, amount) +} + +// SendAccountRequest creates an add AddAccount request message. +func (n Network) SendAccountRequest( + ctx context.Context, + launchID uint64, + address string, + amount sdk.Coins, +) error { + addr, err := n.account.Address(networktypes.SPN) + if err != nil { + return err + } + + msg := launchtypes.NewMsgSendRequest( + addr, + launchID, + launchtypes.NewGenesisAccount( + launchID, + address, + amount, + ), + ) + + n.ev.Send("Broadcasting account transactions", events.ProgressStarted()) + + res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) + if err != nil { + return err + } + + var requestRes launchtypes.MsgSendRequestResponse + if err := res.Decode(&requestRes); err != nil { + return err + } + + if requestRes.AutoApproved { + n.ev.Send( + "Account added to the network by the coordinator!", + events.Icon(icons.Bullet), + events.ProgressFinished(), + ) + } else { + n.ev.Send( + fmt.Sprintf("Request %d to add account to the network has been submitted!", requestRes.RequestID), + events.Icon(icons.Bullet), + events.ProgressFinished(), + ) + } + return nil +} + +// SendValidatorRequest creates the RequestAddValidator message into the SPN +func (n Network) SendValidatorRequest( ctx context.Context, launchID uint64, peer launchtypes.Peer, diff --git a/ignite/services/network/publish.go b/ignite/services/network/publish.go index 43a0acf9d3..f5970359de 100644 --- a/ignite/services/network/publish.go +++ b/ignite/services/network/publish.go @@ -2,7 +2,6 @@ package network import ( "context" - "fmt" "os" "path/filepath" @@ -262,57 +261,3 @@ func (n Network) Publish(ctx context.Context, c Chain, options ...PublishOption) return launchID, campaignID, nil } - -func (n Network) SendAccountRequestForCoordinator(ctx context.Context, launchID uint64, amount sdk.Coins) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - return n.sendAccountRequest(ctx, launchID, addr, amount) -} - -// SendAccountRequest creates an add AddAccount request message. -func (n Network) sendAccountRequest( - ctx context.Context, - launchID uint64, - address string, - amount sdk.Coins, -) error { - addr, err := n.account.Address(networktypes.SPN) - if err != nil { - return err - } - - msg := launchtypes.NewMsgSendRequest( - addr, - launchID, - launchtypes.NewGenesisAccount( - launchID, - address, - amount, - ), - ) - - n.ev.Send("Broadcasting account transactions", events.ProgressStarted()) - - res, err := n.cosmos.BroadcastTx(ctx, n.account, msg) - if err != nil { - return err - } - - var requestRes launchtypes.MsgSendRequestResponse - if err := res.Decode(&requestRes); err != nil { - return err - } - - if requestRes.AutoApproved { - n.ev.Send("Account added to the network by the coordinator!", events.ProgressFinished()) - } else { - n.ev.Send( - fmt.Sprintf("Request %d to add account to the network has been submitted!", requestRes.RequestID), - events.ProgressFinished(), - ) - } - return nil -}