From ec6ef9b3f13621b3dd4bc0a25b7bad36adac5ed5 Mon Sep 17 00:00:00 2001 From: Sahith Reddy Narahari Date: Thu, 5 Dec 2019 20:52:08 +0530 Subject: [PATCH 1/5] Added test input for keeper --- .../internal/keeper/test_common.go | 75 +++++++++++++++---- x/msg_authorization/test_common.go | 3 + 2 files changed, 62 insertions(+), 16 deletions(-) create mode 100644 x/msg_authorization/test_common.go diff --git a/x/msg_authorization/internal/keeper/test_common.go b/x/msg_authorization/internal/keeper/test_common.go index 97a0e177613c..988e873a6c51 100644 --- a/x/msg_authorization/internal/keeper/test_common.go +++ b/x/msg_authorization/internal/keeper/test_common.go @@ -1,28 +1,40 @@ package keeper import ( + "testing" + "time" + + "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" + abci "github.com/tendermint/tendermint/abci/types" + "github.com/tendermint/tendermint/libs/log" dbm "github.com/tendermint/tm-db" + "github.com/cosmos/cosmos-sdk/baseapp" "github.com/cosmos/cosmos-sdk/codec" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/msg_authorization/internal/types" "github.com/cosmos/cosmos-sdk/x/params" + "github.com/cosmos/cosmos-sdk/x/staking" + "github.com/cosmos/cosmos-sdk/x/supply" ) -type testInput struct { - cdc *codec.Codec - ctx sdk.Context - ak auth.AccountKeeper - pk params.Keeper - bk bank.Keeper - dk Keeper - router sdk.Router -} +func makeTestCodec() *codec.Codec { + var cdc = codec.New() + auth.RegisterCodec(cdc) + types.RegisterCodec(cdc) + supply.RegisterCodec(cdc) + staking.RegisterCodec(cdc) + sdk.RegisterCodec(cdc) + codec.RegisterCrypto(cdc) -func setupTestInput() testInput { + return cdc +} +func setupTestInput(t *testing.T) (sdk.Context, auth.AccountKeeper, params.Keeper, bank.BaseKeeper, Keeper, sdk.Router) { db := dbm.NewMemDB() cdc := codec.New() @@ -31,13 +43,44 @@ func setupTestInput() testInput { sdk.RegisterCodec(cdc) codec.RegisterCrypto(cdc) - //TODO create test input - return testInput{} + keyAcc := sdk.NewKVStoreKey(auth.StoreKey) + keyParams := sdk.NewKVStoreKey(params.StoreKey) + keyAuthorization := sdk.NewKVStoreKey(types.StoreKey) + tkeyParams := sdk.NewTransientStoreKey(params.TStoreKey) + + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) + + err := ms.LoadLatestVersion() + require.Nil(t, err) + + ctx := sdk.NewContext(ms, abci.Header{Time: time.Unix(0, 0)}, false, log.NewNopLogger()) + cdc = makeTestCodec() + + blacklistedAddrs := make(map[string]bool) + + paramsKeeper := params.NewKeeper(cdc, keyParams, tkeyParams, params.DefaultCodespace) + authKeeper := auth.NewAccountKeeper(cdc, keyAcc, paramsKeeper.Subspace(auth.DefaultParamspace), auth.ProtoBaseAccount) + bankKeeper := bank.NewBaseKeeper(authKeeper, paramsKeeper.Subspace(bank.DefaultParamspace), bank.DefaultCodespace, blacklistedAddrs) + bankKeeper.SetSendEnabled(ctx, true) + + router := baseapp.NewRouter() + router.AddRoute("bank", bank.NewHandler(bankKeeper)) + + authorizationKeeper := NewKeeper(keyAuthorization, cdc, router) + + authKeeper.SetParams(ctx, auth.DefaultParams()) + + return ctx, authKeeper, paramsKeeper, bankKeeper, authorizationKeeper, router } var ( - senderPub = ed25519.GenPrivKey().PubKey() - recipientPub = ed25519.GenPrivKey().PubKey() - senderAddr = sdk.AccAddress(senderPub.Address()) - recipientAddr = sdk.AccAddress(recipientPub.Address()) + senderPub = ed25519.GenPrivKey().PubKey() + recipientPub = ed25519.GenPrivKey().PubKey() + authorizedPub = ed25519.GenPrivKey().PubKey() + senderAddr = sdk.AccAddress(senderPub.Address()) + recipientAddr = sdk.AccAddress(recipientPub.Address()) + authorizedAddr = sdk.AccAddress(authorizedPub.Address()) ) diff --git a/x/msg_authorization/test_common.go b/x/msg_authorization/test_common.go new file mode 100644 index 000000000000..d0cb9b8dfcc2 --- /dev/null +++ b/x/msg_authorization/test_common.go @@ -0,0 +1,3 @@ +package msg_authorization + +//TODO create a mock app to demonstrate msg_authorization functionality From b50902a8381afaad8d1b910f19b84aa712ae8125 Mon Sep 17 00:00:00 2001 From: Sahith Reddy Narahari Date: Mon, 9 Dec 2019 20:06:35 +0530 Subject: [PATCH 2/5] Added tests for keeper --- x/msg_authorization/handler.go | 23 +++++++- .../internal/keeper/keeper_test.go | 55 ++++++++++++++++++- .../internal/keeper/test_common.go | 20 +++---- x/msg_authorization/internal/types/events.go | 13 +++++ 4 files changed, 97 insertions(+), 14 deletions(-) create mode 100644 x/msg_authorization/internal/types/events.go diff --git a/x/msg_authorization/handler.go b/x/msg_authorization/handler.go index 9684b5c01187..c1a496fe679d 100644 --- a/x/msg_authorization/handler.go +++ b/x/msg_authorization/handler.go @@ -4,6 +4,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/distribution/types" ) func NewHandler(k Keeper) sdk.Handler { @@ -24,12 +25,30 @@ func NewHandler(k Keeper) sdk.Handler { } func handleMsgGrantAuthorization(ctx sdk.Context, msg MsgGrantAuthorization, k Keeper) sdk.Result { - //TODO + k.Grant(ctx, msg.Grantee, msg.Granter, msg.Capability, msg.Expiration) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Granter.String()), + ), + ) + return sdk.Result{Events: ctx.EventManager().Events()} } func handleMsgRevokeAuthorization(ctx sdk.Context, msg MsgRevokeAuthorization, k Keeper) sdk.Result { - //TODO + k.Revoke(ctx, msg.Grantee, msg.Granter, msg.CapabilityMsgType) + + ctx.EventManager().EmitEvent( + sdk.NewEvent( + sdk.EventTypeMessage, + sdk.NewAttribute(sdk.AttributeKeyModule, types.AttributeValueCategory), + sdk.NewAttribute(sdk.AttributeKeySender, msg.Granter.String()), + ), + ) + return sdk.Result{Events: ctx.EventManager().Events()} } diff --git a/x/msg_authorization/internal/keeper/keeper_test.go b/x/msg_authorization/internal/keeper/keeper_test.go index 9429264902a9..a846474bf037 100644 --- a/x/msg_authorization/internal/keeper/keeper_test.go +++ b/x/msg_authorization/internal/keeper/keeper_test.go @@ -1 +1,54 @@ -package keeper_test +package keeper + +import ( + "testing" + "time" + + "github.com/stretchr/testify/require" + "github.com/stretchr/testify/suite" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/msg_authorization/internal/types" + "github.com/cosmos/cosmos-sdk/x/params" +) + +type TestSuite struct { + suite.Suite + ctx sdk.Context + accountKeeper auth.AccountKeeper + paramsKeeper params.Keeper + bankKeeper bank.Keeper + keeper Keeper + router sdk.Router +} + +func (s *TestSuite) SetupTest() { + s.ctx, s.accountKeeper, s.paramsKeeper, s.bankKeeper, s.keeper, s.router = SetupTestInput() + +} + +func (s *TestSuite) TestKeeper(t *testing.T) { + err := s.bankKeeper.SetCoins(s.ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000))) + require.Nil(t, err) + require.True(t, s.bankKeeper.GetCoins(s.ctx, granterAddr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("steak", 10000)))) + + t.Log("Verify that no capability returns nil") + capability, _ := s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) + s.Require().Nil(capability) + //require.Nil(t, expiration) + now := s.ctx.BlockHeader().Time + require.NotNil(t, now) + + newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100)) + s.keeper.Grant(s.ctx, granterAddr, granteeAddr, types.SendCapability{SpendLimit: newCoins}, now.Add(-1*time.Hour)) + capability, expiration := s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) + require.NotNil(t, capability) + require.NotNil(t, expiration) + //TODO add more cases +} + +func TestTestSuite(t *testing.T) { + suite.Run(t, new(TestSuite)) +} diff --git a/x/msg_authorization/internal/keeper/test_common.go b/x/msg_authorization/internal/keeper/test_common.go index 988e873a6c51..f7874ff21cfe 100644 --- a/x/msg_authorization/internal/keeper/test_common.go +++ b/x/msg_authorization/internal/keeper/test_common.go @@ -1,10 +1,8 @@ package keeper import ( - "testing" "time" - "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto/ed25519" abci "github.com/tendermint/tendermint/abci/types" @@ -34,7 +32,7 @@ func makeTestCodec() *codec.Codec { return cdc } -func setupTestInput(t *testing.T) (sdk.Context, auth.AccountKeeper, params.Keeper, bank.BaseKeeper, Keeper, sdk.Router) { +func SetupTestInput() (sdk.Context, auth.AccountKeeper, params.Keeper, bank.BaseKeeper, Keeper, sdk.Router) { db := dbm.NewMemDB() cdc := codec.New() @@ -51,10 +49,10 @@ func setupTestInput(t *testing.T) (sdk.Context, auth.AccountKeeper, params.Keepe ms := store.NewCommitMultiStore(db) ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(keyParams, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(keyAuthorization, sdk.StoreTypeIAVL, db) ms.MountStoreWithDB(tkeyParams, sdk.StoreTypeTransient, db) - err := ms.LoadLatestVersion() - require.Nil(t, err) + ms.LoadLatestVersion() ctx := sdk.NewContext(ms, abci.Header{Time: time.Unix(0, 0)}, false, log.NewNopLogger()) cdc = makeTestCodec() @@ -77,10 +75,10 @@ func setupTestInput(t *testing.T) (sdk.Context, auth.AccountKeeper, params.Keepe } var ( - senderPub = ed25519.GenPrivKey().PubKey() - recipientPub = ed25519.GenPrivKey().PubKey() - authorizedPub = ed25519.GenPrivKey().PubKey() - senderAddr = sdk.AccAddress(senderPub.Address()) - recipientAddr = sdk.AccAddress(recipientPub.Address()) - authorizedAddr = sdk.AccAddress(authorizedPub.Address()) + granteePub = ed25519.GenPrivKey().PubKey() + granterPub = ed25519.GenPrivKey().PubKey() + recepientPub = ed25519.GenPrivKey().PubKey() + granteeAddr = sdk.AccAddress(granteePub.Address()) + granterAddr = sdk.AccAddress(granterPub.Address()) + recepientAddr = sdk.AccAddress(recepientPub.Address()) ) diff --git a/x/msg_authorization/internal/types/events.go b/x/msg_authorization/internal/types/events.go new file mode 100644 index 000000000000..823ad3ce8cc5 --- /dev/null +++ b/x/msg_authorization/internal/types/events.go @@ -0,0 +1,13 @@ +package types + +// msg_authorization module events +const ( + EventGrantAuthorization = "grant-authorization" + EventRevokeAuthorization = "revoke-authorization" + EventExecuteAuthorization = "execute-authorization" + + AttributeKeyGranteeAddress = "grantee" + AttributeKeyGranterAddress = "granter" + + AttributeValueCategory = ModuleName +) From 6c43fd543755bf1e4c9d710f9c748c15f815fa34 Mon Sep 17 00:00:00 2001 From: sahith-narahari Date: Mon, 9 Dec 2019 21:11:00 +0530 Subject: [PATCH 3/5] Added grant,revoke to cli --- x/msg_authorization/client/cli/tx.go | 73 ++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 4 deletions(-) diff --git a/x/msg_authorization/client/cli/tx.go b/x/msg_authorization/client/cli/tx.go index 47244a825235..9242e3f61dff 100644 --- a/x/msg_authorization/client/cli/tx.go +++ b/x/msg_authorization/client/cli/tx.go @@ -1,8 +1,13 @@ package cli import ( + "bufio" "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/msg_authorization/internal/types" "github.com/spf13/cobra" ) @@ -12,6 +17,7 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { AuthorizationTxCmd := &cobra.Command{ Use: types.ModuleName, Short: "Authorization transactions subcommands", + Long: "Authorize and revoke access to execute transactions on behalf of your address", DisableFlagParsing: true, SuggestionsMinimumDistance: 2, RunE: client.ValidateCmd, @@ -26,11 +32,70 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command { } func GetCmdGrantCapability(cdc *codec.Codec) *cobra.Command { - //TODO - return nil + cmd := &cobra.Command{ + Use: "grant", + Short: "Grant authorization to an address", + Long: "Grant authorization to an address to execute a transaction on your behalf", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) + + granter := cliCtx.FromAddress + grantee, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + var capability types.Capability + err = cdc.UnmarshalJSON([]byte(args[1]), &capability) + if err != nil { + return err + } + + msg := types.NewMsgGrantAuthorization(granter, grantee, capability, expiration) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, []sdk.Msg{msg}) + + }, + } + return cmd } func GetCmdRevokeCapability(cdc *codec.Codec) *cobra.Command { - //TODO - return nil + cmd := &cobra.Command{ + Use: "revoke", + Short: "revoke authorization", + Long: "revoke authorization from an address for a transaction", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + inBuf := bufio.NewReader(cmd.InOrStdin()) + txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc)) + cliCtx := context.NewCLIContextWithInput(inBuf).WithCodec(cdc) + + granter := cliCtx.FromAddress + grantee, err := sdk.AccAddressFromBech32(args[0]) + if err != nil { + return err + } + + var msgAuthorized sdk.Msg + err = cdc.UnmarshalJSON([]byte(args[1]), &msgAuthorized) + if err != nil { + return err + } + + msg := types.NewMsgRevokeAuthorization(granter, grantee, msgAuthorized) + if err := msg.ValidateBasic(); err != nil { + return err + } + + return utils.CompleteAndBroadcastTxCLI(txBldr, cliCtx, []sdk.Msg{msg}) + }, + } + return cmd } From 47b2974502ab5003d4cab8eb0e007cd6d47fa71b Mon Sep 17 00:00:00 2001 From: sahith-narahari Date: Tue, 10 Dec 2019 13:16:55 +0530 Subject: [PATCH 4/5] Added more test cases for keeper --- .../internal/keeper/keeper_test.go | 43 ++++++++++++++----- x/msg_authorization/internal/types/codec.go | 4 ++ 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/x/msg_authorization/internal/keeper/keeper_test.go b/x/msg_authorization/internal/keeper/keeper_test.go index a846474bf037..76fafcdb3e52 100644 --- a/x/msg_authorization/internal/keeper/keeper_test.go +++ b/x/msg_authorization/internal/keeper/keeper_test.go @@ -4,7 +4,6 @@ import ( "testing" "time" - "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" sdk "github.com/cosmos/cosmos-sdk/types" @@ -29,24 +28,48 @@ func (s *TestSuite) SetupTest() { } -func (s *TestSuite) TestKeeper(t *testing.T) { +func (s *TestSuite) TestKeeper() { err := s.bankKeeper.SetCoins(s.ctx, granterAddr, sdk.NewCoins(sdk.NewInt64Coin("steak", 10000))) - require.Nil(t, err) - require.True(t, s.bankKeeper.GetCoins(s.ctx, granterAddr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("steak", 10000)))) + s.Require().Nil(err) + s.Require().True(s.bankKeeper.GetCoins(s.ctx, granterAddr).IsEqual(sdk.NewCoins(sdk.NewInt64Coin("steak", 10000)))) - t.Log("Verify that no capability returns nil") + s.T().Log("Verify that no capability returns nil") capability, _ := s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) s.Require().Nil(capability) //require.Nil(t, expiration) now := s.ctx.BlockHeader().Time - require.NotNil(t, now) + s.Require().NotNil(now) newCoins := sdk.NewCoins(sdk.NewInt64Coin("steak", 100)) + s.T().Log("Verify if expired capability is rejected") s.keeper.Grant(s.ctx, granterAddr, granteeAddr, types.SendCapability{SpendLimit: newCoins}, now.Add(-1*time.Hour)) - capability, expiration := s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) - require.NotNil(t, capability) - require.NotNil(t, expiration) - //TODO add more cases + capability, _ = s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) + s.Require().Nil(capability) + + s.T().Log("Verify if capability is accepted") + s.keeper.Grant(s.ctx, granteeAddr, granterAddr, types.SendCapability{SpendLimit: newCoins}, now.Add(time.Hour)) + capability, _ = s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) + s.Require().NotNil(capability) + s.Require().Equal(capability.MsgType(), bank.MsgSend{}) + + s.T().Log("Verify fetching capability with wrong msg type fails") + capability, _ = s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgMultiSend{}) + s.Require().Nil(capability) + + s.T().Log("Verify fetching capability with wrong grantee fails") + capability, _ = s.keeper.GetCapability(s.ctx, recepientAddr, granterAddr, bank.MsgMultiSend{}) + s.Require().Nil(capability) + + s.T().Log("Verify revoke fails with wrong information") + s.keeper.Revoke(s.ctx, recepientAddr, granterAddr, bank.MsgSend{}) + capability, _ = s.keeper.GetCapability(s.ctx, recepientAddr, granterAddr, bank.MsgSend{}) + s.Require().Nil(capability) + + s.T().Log("Verify revoke executes with correct information") + s.keeper.Revoke(s.ctx, recepientAddr, granterAddr, bank.MsgSend{}) + capability, _ = s.keeper.GetCapability(s.ctx, granteeAddr, granterAddr, bank.MsgSend{}) + s.Require().NotNil(capability) + } func TestTestSuite(t *testing.T) { diff --git a/x/msg_authorization/internal/types/codec.go b/x/msg_authorization/internal/types/codec.go index d9f8eb7ba7f6..b6003860776a 100644 --- a/x/msg_authorization/internal/types/codec.go +++ b/x/msg_authorization/internal/types/codec.go @@ -10,4 +10,8 @@ func RegisterCodec(cdc *codec.Codec) { cdc.RegisterConcrete(MsgGrantAuthorization{}, "cosmos-sdk/GrantAuthorization", nil) cdc.RegisterConcrete(MsgRevokeAuthorization{}, "cosmos-sdk/RevokeAuthorization", nil) cdc.RegisterConcrete(MsgExecDelegated{}, "cosmos-sdk/ExecDelegated", nil) + cdc.RegisterConcrete(SendCapability{}, "cosmos-sdk/SendCapability", nil) + cdc.RegisterConcrete(CapabilityGrant{}, "cosmos-sdk/CapabilityGrant", nil) + + cdc.RegisterInterface((*Capability)(nil), nil) } From a92593f1e55219731f1ec37cdf9ef948e7ce08ff Mon Sep 17 00:00:00 2001 From: Sahith Reddy Narahari Date: Tue, 10 Dec 2019 19:53:49 +0530 Subject: [PATCH 5/5] Added expiration flag to grant tx --- x/msg_authorization/client/cli/flags.go | 3 +++ x/msg_authorization/client/cli/tx.go | 10 ++++++++++ 2 files changed, 13 insertions(+) create mode 100644 x/msg_authorization/client/cli/flags.go diff --git a/x/msg_authorization/client/cli/flags.go b/x/msg_authorization/client/cli/flags.go new file mode 100644 index 000000000000..a77534c3551f --- /dev/null +++ b/x/msg_authorization/client/cli/flags.go @@ -0,0 +1,3 @@ +package cli + +const FlagExpiration = "expiration" diff --git a/x/msg_authorization/client/cli/tx.go b/x/msg_authorization/client/cli/tx.go index 9242e3f61dff..ff33d7fa57ae 100644 --- a/x/msg_authorization/client/cli/tx.go +++ b/x/msg_authorization/client/cli/tx.go @@ -2,6 +2,8 @@ package cli import ( "bufio" + "time" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" "github.com/cosmos/cosmos-sdk/codec" @@ -10,6 +12,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/client/utils" "github.com/cosmos/cosmos-sdk/x/msg_authorization/internal/types" "github.com/spf13/cobra" + "github.com/spf13/viper" ) // GetTxCmd returns the transaction commands for this module @@ -53,6 +56,11 @@ func GetCmdGrantCapability(cdc *codec.Codec) *cobra.Command { if err != nil { return err } + expirationString := viper.GetString(FlagExpiration) + expiration, err := time.Parse(time.RFC3339, expirationString) + if err != nil { + return err + } msg := types.NewMsgGrantAuthorization(granter, grantee, capability, expiration) if err := msg.ValidateBasic(); err != nil { @@ -63,6 +71,8 @@ func GetCmdGrantCapability(cdc *codec.Codec) *cobra.Command { }, } + cmd.Flags().String(FlagExpiration, "9999-12-31 23:59:59.52Z", "The time upto which the authorization is active for the user") + return cmd }