diff --git a/api/cosmos/nft/v1beta1/event.pulsar.go b/api/cosmos/nft/v1beta1/event.pulsar.go index e67deb473..16b7a6c26 100644 --- a/api/cosmos/nft/v1beta1/event.pulsar.go +++ b/api/cosmos/nft/v1beta1/event.pulsar.go @@ -1739,9 +1739,13 @@ type EventSend struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"` + // class_id associated with the nft + ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // id is a unique identifier of the nft + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // sender is the address of the owner of nft + Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"` + // receiver is the receiver address of nft Receiver string `protobuf:"bytes,4,opt,name=receiver,proto3" json:"receiver,omitempty"` } @@ -1799,9 +1803,12 @@ type EventMint struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` + // id is a unique identifier of the nft + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` } func (x *EventMint) Reset() { @@ -1851,9 +1858,12 @@ type EventBurn struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` + // id is a unique identifier of the nft + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` } func (x *EventBurn) Reset() { diff --git a/api/cosmos/nft/v1beta1/genesis.pulsar.go b/api/cosmos/nft/v1beta1/genesis.pulsar.go index 98980a0e4..c2a085a30 100644 --- a/api/cosmos/nft/v1beta1/genesis.pulsar.go +++ b/api/cosmos/nft/v1beta1/genesis.pulsar.go @@ -1223,6 +1223,7 @@ type GenesisState struct { // class defines the class of the nft type. Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"` + // entry defines all nft owned by a person. Entries []*Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` } diff --git a/api/cosmos/nft/v1beta1/query.pulsar.go b/api/cosmos/nft/v1beta1/query.pulsar.go index f045f7094..cfcb7d51b 100644 --- a/api/cosmos/nft/v1beta1/query.pulsar.go +++ b/api/cosmos/nft/v1beta1/query.pulsar.go @@ -6567,8 +6567,10 @@ type QueryBalanceRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` } func (x *QueryBalanceRequest) Reset() { @@ -6611,6 +6613,7 @@ type QueryBalanceResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // amount is the number of all NFTs of a given class owned by the owner Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"` } @@ -6647,8 +6650,10 @@ type QueryOwnerRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // id is a unique identifier of the NFT + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` } func (x *QueryOwnerRequest) Reset() { @@ -6691,6 +6696,7 @@ type QueryOwnerResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // owner is the owner address of the nft Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` } @@ -6727,6 +6733,7 @@ type QuerySupplyRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` } @@ -6763,6 +6770,7 @@ type QuerySupplyResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // amount is the number of all NFTs from the given class Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"` } @@ -6799,8 +6807,11 @@ type QueryNFTsRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + // class_id associated with the nft + ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + // pagination defines an optional pagination for the request. Pagination *v1beta1.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -6851,7 +6862,9 @@ type QueryNFTsResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Nfts []*NFT `protobuf:"bytes,1,rep,name=nfts,proto3" json:"nfts,omitempty"` + // NFT defines the NFT + Nfts []*NFT `protobuf:"bytes,1,rep,name=nfts,proto3" json:"nfts,omitempty"` + // pagination defines the pagination in the response. Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -6895,8 +6908,10 @@ type QueryNFTRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // id is a unique identifier of the NFT + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` } func (x *QueryNFTRequest) Reset() { @@ -6939,6 +6954,7 @@ type QueryNFTResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // owner is the owner address of the nft Nft *NFT `protobuf:"bytes,1,opt,name=nft,proto3" json:"nft,omitempty"` } @@ -6975,6 +6991,7 @@ type QueryClassRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` } @@ -7011,6 +7028,7 @@ type QueryClassResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + // class defines the class of the nft type. Class *Class `protobuf:"bytes,1,opt,name=class,proto3" json:"class,omitempty"` } @@ -7084,7 +7102,9 @@ type QueryClassesResponse struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"` + // class defines the class of the nft type. + Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"` + // pagination defines the pagination in the response. Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } diff --git a/proto/cosmos/crisis/v1beta1/tx.proto b/proto/cosmos/crisis/v1beta1/tx.proto index fc9a3fcee..80663e35a 100644 --- a/proto/cosmos/crisis/v1beta1/tx.proto +++ b/proto/cosmos/crisis/v1beta1/tx.proto @@ -32,13 +32,13 @@ message MsgVerifyInvariant { option (gogoproto.goproto_getters) = false; // sender is the account address of private key to send coins to fee collector account. - string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; - + string sender = 1 [(cosmos_proto.scalar) = "cosmos.AddressString"]; + // name of the invariant module. string invariant_module_name = 2; // invariant_route is the msg's invariant route. - string invariant_route = 3; + string invariant_route = 3; } // MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type. diff --git a/proto/cosmos/nft/v1beta1/event.proto b/proto/cosmos/nft/v1beta1/event.proto index 96964f08a..2f6d5a0d2 100644 --- a/proto/cosmos/nft/v1beta1/event.proto +++ b/proto/cosmos/nft/v1beta1/event.proto @@ -5,22 +5,39 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/nft"; // EventSend is emitted on Msg/Send message EventSend { + // class_id associated with the nft string class_id = 1; - string id = 2; - string sender = 3; + + // id is a unique identifier of the nft + string id = 2; + + // sender is the address of the owner of nft + string sender = 3; + + // receiver is the receiver address of nft string receiver = 4; } // EventMint is emitted on Mint message EventMint { + // class_id associated with the nft string class_id = 1; - string id = 2; - string owner = 3; + + // id is a unique identifier of the nft + string id = 2; + + // owner is the owner address of the nft + string owner = 3; } // EventBurn is emitted on Burn message EventBurn { + // class_id associated with the nft string class_id = 1; - string id = 2; - string owner = 3; + + // id is a unique identifier of the nft + string id = 2; + + // owner is the owner address of the nft + string owner = 3; } diff --git a/proto/cosmos/nft/v1beta1/genesis.proto b/proto/cosmos/nft/v1beta1/genesis.proto index 6f36ed34d..75b5245a9 100644 --- a/proto/cosmos/nft/v1beta1/genesis.proto +++ b/proto/cosmos/nft/v1beta1/genesis.proto @@ -9,7 +9,9 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/nft"; message GenesisState { // class defines the class of the nft type. repeated cosmos.nft.v1beta1.Class classes = 1; - repeated Entry entries = 2; + + // entry defines all nft owned by a person. + repeated Entry entries = 2; } // Entry Defines all nft owned by a person diff --git a/proto/cosmos/nft/v1beta1/query.proto b/proto/cosmos/nft/v1beta1/query.proto index c1d8070f4..ae482e4ce 100644 --- a/proto/cosmos/nft/v1beta1/query.proto +++ b/proto/cosmos/nft/v1beta1/query.proto @@ -48,67 +48,91 @@ service Query { // QueryBalanceRequest is the request type for the Query/Balance RPC method message QueryBalanceRequest { + // class_id associated with the nft string class_id = 1; - string owner = 2; + + // owner is the owner address of the nft + string owner = 2; } // QueryBalanceResponse is the response type for the Query/Balance RPC method message QueryBalanceResponse { + // amount is the number of all NFTs of a given class owned by the owner uint64 amount = 1; } // QueryOwnerRequest is the request type for the Query/Owner RPC method message QueryOwnerRequest { + // class_id associated with the nft string class_id = 1; - string id = 2; + + // id is a unique identifier of the NFT + string id = 2; } // QueryOwnerResponse is the response type for the Query/Owner RPC method message QueryOwnerResponse { + // owner is the owner address of the nft string owner = 1; } // QuerySupplyRequest is the request type for the Query/Supply RPC method message QuerySupplyRequest { + // class_id associated with the nft string class_id = 1; } // QuerySupplyResponse is the response type for the Query/Supply RPC method message QuerySupplyResponse { + // amount is the number of all NFTs from the given class uint64 amount = 1; } // QueryNFTstRequest is the request type for the Query/NFTs RPC method message QueryNFTsRequest { - string class_id = 1; - string owner = 2; + // class_id associated with the nft + string class_id = 1; + + // owner is the owner address of the nft + string owner = 2; + + // pagination defines an optional pagination for the request. cosmos.base.query.v1beta1.PageRequest pagination = 3; } // QueryNFTsResponse is the response type for the Query/NFTs RPC methods message QueryNFTsResponse { - repeated cosmos.nft.v1beta1.NFT nfts = 1; + // NFT defines the NFT + repeated cosmos.nft.v1beta1.NFT nfts = 1; + + // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } // QueryNFTRequest is the request type for the Query/NFT RPC method message QueryNFTRequest { + // class_id associated with the nft string class_id = 1; - string id = 2; + + // id is a unique identifier of the NFT + string id = 2; } // QueryNFTResponse is the response type for the Query/NFT RPC method message QueryNFTResponse { + // owner is the owner address of the nft cosmos.nft.v1beta1.NFT nft = 1; } // QueryClassRequest is the request type for the Query/Class RPC method message QueryClassRequest { + // class_id associated with the nft string class_id = 1; } // QueryClassResponse is the response type for the Query/Class RPC method message QueryClassResponse { + // class defines the class of the nft type. cosmos.nft.v1beta1.Class class = 1; } @@ -120,6 +144,9 @@ message QueryClassesRequest { // QueryClassesResponse is the response type for the Query/Classes RPC method message QueryClassesResponse { - repeated cosmos.nft.v1beta1.Class classes = 1; + // class defines the class of the nft type. + repeated cosmos.nft.v1beta1.Class classes = 1; + + // pagination defines the pagination in the response. cosmos.base.query.v1beta1.PageResponse pagination = 2; } diff --git a/x/nft/client/cli/query_test.go b/x/nft/client/cli/query_test.go index a8bd55ed1..540d4d8c9 100644 --- a/x/nft/client/cli/query_test.go +++ b/x/nft/client/cli/query_test.go @@ -1,9 +1,13 @@ package cli_test import ( + "context" "fmt" + "io" + "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/flags" + svrcmd "github.com/cosmos/cosmos-sdk/server/cmd" "github.com/cosmos/cosmos-sdk/testutil" clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli" "github.com/cosmos/cosmos-sdk/x/nft" @@ -12,111 +16,119 @@ import ( func (s *CLITestSuite) TestQueryClass() { testCases := []struct { - name string - args struct { - ClassID string - } - expectErr bool + name string + args []string + expCmdOutput string }{ { - name: "valid case", - args: struct { - ClassID string - }{ - ClassID: testClassID, - }, - expectErr: false, + name: "json output", + args: []string{testClassID, fmt.Sprintf("--%s=json", flags.FlagOutput)}, + expCmdOutput: `[kitty --output=json]`, + }, + { + name: "text output", + args: []string{testClassID, fmt.Sprintf("--%s=text", flags.FlagOutput)}, + expCmdOutput: `[kitty --output=text]`, }, } for _, tc := range testCases { s.Run(tc.name, func() { cmd := cli.GetCmdQueryClass() - var args []string - args = append(args, tc.args.ClassID) - args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput)) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - var result nft.QueryClassResponse - err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result) - s.Require().NoError(err) - } + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd.SetOut(io.Discard) + s.Require().NotNil(cmd) + + cmd.SetContext(ctx) + cmd.SetArgs(tc.args) + s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) + + s.Require().Contains(fmt.Sprint(cmd), "class [class-id] [] [] query an NFT class based on its id") + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) + s.Require().NoError(err) }) } } func (s *CLITestSuite) TestQueryClasses() { testCases := []struct { - name string - expectErr bool + name string + flagArgs []string + expCmdOutput string }{ { - name: "no params", - expectErr: false, + name: "json output", + flagArgs: []string{fmt.Sprintf("--%s=json", flags.FlagOutput)}, + expCmdOutput: `[--output=json]`, + }, + { + name: "text output", + flagArgs: []string{fmt.Sprintf("--%s=text", flags.FlagOutput)}, + expCmdOutput: `[--output=text]`, }, } for _, tc := range testCases { s.Run(tc.name, func() { cmd := cli.GetCmdQueryClasses() - var args []string - args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput)) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - var result nft.QueryClassesResponse - err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result) - s.Require().NoError(err) - } + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd.SetOut(io.Discard) + s.Require().NotNil(cmd) + + cmd.SetContext(ctx) + cmd.SetArgs(tc.flagArgs) + s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) + + s.Require().Contains(fmt.Sprint(cmd), "classes [] [] query all NFT classes") + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.flagArgs) + s.Require().NoError(err) }) } } func (s *CLITestSuite) TestQueryNFT() { testCases := []struct { - name string - args struct { - ClassID string - ID string - } - expectErr bool + name string + args []string + expCmdOutput string }{ { - name: "valid case", - args: struct { - ClassID string - ID string - }{ - ClassID: testClassID, - ID: testID, - }, - expectErr: false, + name: "json output", + args: []string{testClassID, testID, fmt.Sprintf("--%s=json", flags.FlagOutput)}, + expCmdOutput: `[kitty kitty1 --output=json]`, + }, + { + name: "text output", + args: []string{testClassID, testID, fmt.Sprintf("--%s=text", flags.FlagOutput)}, + expCmdOutput: `[kitty kitty1 --output=text]`, }, } for _, tc := range testCases { s.Run(tc.name, func() { cmd := cli.GetCmdQueryNFT() - var args []string - args = append(args, tc.args.ClassID) - args = append(args, tc.args.ID) - args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput)) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - var result nft.QueryNFTResponse - err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result) - s.Require().NoError(err) - } + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd.SetOut(io.Discard) + s.Require().NotNil(cmd) + + cmd.SetContext(ctx) + cmd.SetArgs(tc.args) + s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) + + s.Require().Contains(fmt.Sprint(cmd), "nft [class-id] [nft-id] [] [] query an NFT based on its class and id") + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) + s.Require().NoError(err) }) } } @@ -131,6 +143,7 @@ func (s *CLITestSuite) TestQueryNFTs() { Owner string } expectErr bool + expErrMsg string }{ { name: "empty class id and owner", @@ -139,6 +152,7 @@ func (s *CLITestSuite) TestQueryNFTs() { Owner string }{}, expectErr: true, + expErrMsg: "must provide at least one of classID or owner", }, { name: "valid case", @@ -164,6 +178,7 @@ func (s *CLITestSuite) TestQueryNFTs() { out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) if tc.expectErr { s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expErrMsg) } else { s.Require().NoError(err) var result nft.QueryNFTsResponse @@ -176,43 +191,40 @@ func (s *CLITestSuite) TestQueryNFTs() { func (s *CLITestSuite) TestQueryOwner() { testCases := []struct { - name string - args struct { - ClassID string - ID string - } - expectErr bool + name string + args []string + expCmdOutput string }{ { - name: "valid case", - args: struct { - ClassID string - ID string - }{ - ClassID: testClassID, - ID: testID, - }, - expectErr: false, + name: "json output", + args: []string{testClassID, testID, fmt.Sprintf("--%s=json", flags.FlagOutput)}, + expCmdOutput: `[kitty kitty1 --output=json]`, + }, + { + name: "text output", + args: []string{testClassID, testID, fmt.Sprintf("--%s=text", flags.FlagOutput)}, + expCmdOutput: `[kitty kitty1 --output=text]`, }, } for _, tc := range testCases { s.Run(tc.name, func() { cmd := cli.GetCmdQueryOwner() - var args []string - args = append(args, tc.args.ClassID) - args = append(args, tc.args.ID) - args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput)) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - var result nft.QueryOwnerResponse - err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result) - s.Require().NoError(err) - } + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd.SetOut(io.Discard) + s.Require().NotNil(cmd) + + cmd.SetContext(ctx) + cmd.SetArgs(tc.args) + s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) + + s.Require().Contains(fmt.Sprint(cmd), "owner [class-id] [nft-id] [] [] query the owner of the NFT based on its class and id") + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) + s.Require().NoError(err) }) } } @@ -221,82 +233,75 @@ func (s *CLITestSuite) TestQueryBalance() { accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) testCases := []struct { - name string - args struct { - ClassID string - Owner string - } - expectErr bool + name string + args []string + expCmdOutput string }{ { - name: "valid case", - args: struct { - ClassID string - Owner string - }{ - ClassID: testClassID, - Owner: accounts[0].Address.String(), - }, - expectErr: false, + name: "json output", + args: []string{accounts[0].Address.String(), testClassID, fmt.Sprintf("--%s=json", flags.FlagOutput)}, + expCmdOutput: fmt.Sprintf("%s kitty --output=json", accounts[0].Address.String()), + }, + { + name: "text output", + args: []string{accounts[0].Address.String(), testClassID, fmt.Sprintf("--%s=text", flags.FlagOutput)}, + expCmdOutput: fmt.Sprintf("%s kitty --output=text", accounts[0].Address.String()), }, } for _, tc := range testCases { s.Run(tc.name, func() { cmd := cli.GetCmdQueryBalance() - var args []string - args = append(args, tc.args.Owner) - args = append(args, tc.args.ClassID) - args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput)) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - var result nft.QueryBalanceResponse - err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result) - s.Require().NoError(err) - } + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd.SetOut(io.Discard) + s.Require().NotNil(cmd) + + cmd.SetContext(ctx) + cmd.SetArgs(tc.args) + s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) + + s.Require().Contains(fmt.Sprint(cmd), "balance [owner] [class-id] [] [] query the number of NFTs of a given class owned by the owner") + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) + s.Require().NoError(err) }) } } func (s *CLITestSuite) TestQuerySupply() { testCases := []struct { - name string - args struct { - ClassID string - } - expectErr bool + name string + args []string + expCmdOutput string }{ { - name: "valid case", - args: struct { - ClassID string - }{ - ClassID: testClassID, - }, - expectErr: false, + name: "valid case", + args: []string{testClassID, fmt.Sprintf("--%s=json", flags.FlagOutput)}, + expCmdOutput: `[kitty --output=json]`, }, } for _, tc := range testCases { s.Run(tc.name, func() { cmd := cli.GetCmdQuerySupply() - var args []string - args = append(args, tc.args.ClassID) - args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput)) - out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) - if tc.expectErr { - s.Require().Error(err) - } else { - s.Require().NoError(err) - var result nft.QuerySupplyResponse - err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result) - s.Require().NoError(err) - } + ctx := svrcmd.CreateExecuteContext(context.Background()) + + cmd.SetOut(io.Discard) + s.Require().NotNil(cmd) + + cmd.SetContext(ctx) + cmd.SetArgs(tc.args) + s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd)) + + s.Require().Contains(fmt.Sprint(cmd), "supply [class-id] [] [] query the number of nft based on the class") + s.Require().Contains(fmt.Sprint(cmd), tc.expCmdOutput) + + _, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, tc.args) + s.Require().NoError(err) }) } } diff --git a/x/nft/client/cli/tx.go b/x/nft/client/cli/tx.go index 45320a97a..4f9c735b8 100644 --- a/x/nft/client/cli/tx.go +++ b/x/nft/client/cli/tx.go @@ -31,6 +31,7 @@ func GetTxCmd() *cobra.Command { return nftTxCmd } +// NewCmdSend creates a CLI command for MsgSend. func NewCmdSend() *cobra.Command { cmd := &cobra.Command{ Use: "send [class-id] [nft-id] [receiver] --from [sender]", diff --git a/x/nft/client/cli/tx_test.go b/x/nft/client/cli/tx_test.go index 7ef912782..dfa63233c 100644 --- a/x/nft/client/cli/tx_test.go +++ b/x/nft/client/cli/tx_test.go @@ -126,7 +126,7 @@ func (s *CLITestSuite) SetupSuite() { func (s *CLITestSuite) TestCLITxSend() { accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1) - args := []string{ + extraArgs := []string{ fmt.Sprintf("--%s=%s", flags.FlagFrom, OwnerName), fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation), fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync), @@ -138,7 +138,41 @@ func (s *CLITestSuite) TestCLITxSend() { args []string expectedCode uint32 expectErr bool + expErrMsg string }{ + { + "class id is empty", + []string{ + "", + testID, + accounts[0].Address.String(), + }, + 0, + true, + "empty class id", + }, + { + "nft id is empty", + []string{ + testClassID, + "", + accounts[0].Address.String(), + }, + 0, + true, + "empty nft id", + }, + { + "invalid receiver address", + []string{ + testClassID, + testID, + "invalid receiver", + }, + 0, + true, + "Invalid receiver address", + }, { "valid transaction", []string{ @@ -148,13 +182,14 @@ func (s *CLITestSuite) TestCLITxSend() { }, 0, false, + "", }, } for _, tc := range testCases { tc := tc s.Run(tc.name, func() { - args = append(args, tc.args...) + args := append(tc.args, extraArgs...) cmd := cli.NewCmdSend() cmd.SetContext(s.ctx) cmd.SetArgs(args) @@ -164,6 +199,7 @@ func (s *CLITestSuite) TestCLITxSend() { out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args) if tc.expectErr { s.Require().Error(err) + s.Require().Contains(err.Error(), tc.expErrMsg) } else { var txResp sdk.TxResponse s.Require().NoError(err) diff --git a/x/nft/codec.go b/x/nft/codec.go index d98e836c3..12a4250cb 100644 --- a/x/nft/codec.go +++ b/x/nft/codec.go @@ -6,6 +6,7 @@ import ( "github.com/cosmos/cosmos-sdk/types/msgservice" ) +// RegisterInterfaces registers the interfaces types with the interface registry. func RegisterInterfaces(registry types.InterfaceRegistry) { registry.RegisterImplementations((*sdk.Msg)(nil), &MsgSend{}, diff --git a/x/nft/errors.go b/x/nft/errors.go index 771146f39..ff8fd1cc1 100644 --- a/x/nft/errors.go +++ b/x/nft/errors.go @@ -6,9 +6,9 @@ import ( // x/nft module sentinel errors var ( - ErrClassExists = errors.Register(ModuleName, 3, "nft class already exist") + ErrClassExists = errors.Register(ModuleName, 3, "nft class already exists") ErrClassNotExists = errors.Register(ModuleName, 4, "nft class does not exist") - ErrNFTExists = errors.Register(ModuleName, 5, "nft already exist") + ErrNFTExists = errors.Register(ModuleName, 5, "nft already exists") ErrNFTNotExists = errors.Register(ModuleName, 6, "nft does not exist") ErrEmptyClassID = errors.Register(ModuleName, 7, "empty class id") ErrEmptyNFTID = errors.Register(ModuleName, 8, "empty nft id") diff --git a/x/nft/event.pb.go b/x/nft/event.pb.go index d5540b618..56950509f 100644 --- a/x/nft/event.pb.go +++ b/x/nft/event.pb.go @@ -24,9 +24,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // EventSend is emitted on Msg/Send type EventSend struct { - ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"` + // class_id associated with the nft + ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // id is a unique identifier of the nft + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // sender is the address of the owner of nft + Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,omitempty"` + // receiver is the receiver address of nft Receiver string `protobuf:"bytes,4,opt,name=receiver,proto3" json:"receiver,omitempty"` } @@ -93,9 +97,12 @@ func (m *EventSend) GetReceiver() string { // EventMint is emitted on Mint type EventMint struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` + // id is a unique identifier of the nft + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` } func (m *EventMint) Reset() { *m = EventMint{} } @@ -154,9 +161,12 @@ func (m *EventMint) GetOwner() string { // EventBurn is emitted on Burn type EventBurn struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` - Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` + // id is a unique identifier of the nft + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"` } func (m *EventBurn) Reset() { *m = EventBurn{} } diff --git a/x/nft/genesis.go b/x/nft/genesis.go index 75124ea35..30b743a68 100644 --- a/x/nft/genesis.go +++ b/x/nft/genesis.go @@ -4,7 +4,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// ValidateGenesis check the given genesis state has no integrity issues +// ValidateGenesis checks that the given genesis state has no integrity issues func ValidateGenesis(data GenesisState) error { for _, class := range data.Classes { if len(class.Id) == 0 { @@ -24,7 +24,7 @@ func ValidateGenesis(data GenesisState) error { return nil } -// DefaultGenesisState - Return a default genesis state +// DefaultGenesisState - Returns a default genesis state func DefaultGenesisState() *GenesisState { return &GenesisState{} } diff --git a/x/nft/genesis.pb.go b/x/nft/genesis.pb.go index 6ad3f3fc5..785ce0e5e 100644 --- a/x/nft/genesis.pb.go +++ b/x/nft/genesis.pb.go @@ -26,6 +26,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package type GenesisState struct { // class defines the class of the nft type. Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"` + // entry defines all nft owned by a person. Entries []*Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"` } diff --git a/x/nft/keeper/class.go b/x/nft/keeper/class.go index d887ec662..00bbd90e1 100644 --- a/x/nft/keeper/class.go +++ b/x/nft/keeper/class.go @@ -20,7 +20,7 @@ func (k Keeper) SaveClass(ctx sdk.Context, class nft.Class) error { return nil } -// UpdateClass defines a method for updating a exist nft class +// UpdateClass defines a method for updating an exist nft class func (k Keeper) UpdateClass(ctx sdk.Context, class nft.Class) error { if !k.HasClass(ctx, class.Id) { return sdkerrors.Wrap(nft.ErrClassNotExists, class.Id) diff --git a/x/nft/keeper/genesis.go b/x/nft/keeper/genesis.go index 116bf0bd2..ff5886e28 100644 --- a/x/nft/keeper/genesis.go +++ b/x/nft/keeper/genesis.go @@ -7,7 +7,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/nft" ) -// InitGenesis new nft genesis +// InitGenesis initializes the nft module's genesis state from a given +// genesis state. func (k Keeper) InitGenesis(ctx sdk.Context, data *nft.GenesisState) { for _, class := range data.Classes { if err := k.SaveClass(ctx, *class); err != nil { diff --git a/x/nft/keeper/grpc_query.go b/x/nft/keeper/grpc_query.go index e409a78c0..0c4026e20 100644 --- a/x/nft/keeper/grpc_query.go +++ b/x/nft/keeper/grpc_query.go @@ -14,10 +14,6 @@ var _ nft.QueryServer = Keeper{} // Balance return the number of NFTs of a given class owned by the owner, same as balanceOf in ERC721 func (k Keeper) Balance(goCtx context.Context, r *nft.QueryBalanceRequest) (*nft.QueryBalanceResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - if len(r.ClassId) == 0 { return nil, nft.ErrEmptyClassID } @@ -34,10 +30,6 @@ func (k Keeper) Balance(goCtx context.Context, r *nft.QueryBalanceRequest) (*nft // Owner return the owner of the NFT based on its class and id, same as ownerOf in ERC721 func (k Keeper) Owner(goCtx context.Context, r *nft.QueryOwnerRequest) (*nft.QueryOwnerResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - if len(r.ClassId) == 0 { return nil, nft.ErrEmptyClassID } @@ -53,10 +45,6 @@ func (k Keeper) Owner(goCtx context.Context, r *nft.QueryOwnerRequest) (*nft.Que // Supply return the number of NFTs from the given class, same as totalSupply of ERC721. func (k Keeper) Supply(goCtx context.Context, r *nft.QuerySupplyRequest) (*nft.QuerySupplyResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - if len(r.ClassId) == 0 { return nil, nft.ErrEmptyClassID } @@ -67,10 +55,6 @@ func (k Keeper) Supply(goCtx context.Context, r *nft.QuerySupplyRequest) (*nft.Q // NFTs queries all NFTs of a given class or owner (at least one must be provided), similar to tokenByIndex in ERC721Enumerable func (k Keeper) NFTs(goCtx context.Context, r *nft.QueryNFTsRequest) (*nft.QueryNFTsResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - var err error var owner sdk.AccAddress @@ -129,10 +113,6 @@ func (k Keeper) NFTs(goCtx context.Context, r *nft.QueryNFTsRequest) (*nft.Query // NFT return an NFT based on its class and id. func (k Keeper) NFT(goCtx context.Context, r *nft.QueryNFTRequest) (*nft.QueryNFTResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - if len(r.ClassId) == 0 { return nil, nft.ErrEmptyClassID } @@ -150,10 +130,6 @@ func (k Keeper) NFT(goCtx context.Context, r *nft.QueryNFTRequest) (*nft.QueryNF // Class return an NFT class based on its id func (k Keeper) Class(goCtx context.Context, r *nft.QueryClassRequest) (*nft.QueryClassResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - if len(r.ClassId) == 0 { return nil, nft.ErrEmptyClassID } @@ -168,10 +144,6 @@ func (k Keeper) Class(goCtx context.Context, r *nft.QueryClassRequest) (*nft.Que // Classes return all NFT classes func (k Keeper) Classes(goCtx context.Context, r *nft.QueryClassesRequest) (*nft.QueryClassesResponse, error) { - if r == nil { - return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") - } - ctx := sdk.UnwrapSDKContext(goCtx) store := ctx.KVStore(k.storeKey) classStore := prefix.NewStore(store, ClassKey) diff --git a/x/nft/keeper/msg_server.go b/x/nft/keeper/msg_server.go index fc14a6055..3fa78a957 100644 --- a/x/nft/keeper/msg_server.go +++ b/x/nft/keeper/msg_server.go @@ -10,7 +10,7 @@ import ( var _ nft.MsgServer = Keeper{} -// Send implement Send method of the types.MsgServer. +// Send implements Send method of the types.MsgServer. func (k Keeper) Send(goCtx context.Context, msg *nft.MsgSend) (*nft.MsgSendResponse, error) { ctx := sdk.UnwrapSDKContext(goCtx) sender, err := sdk.AccAddressFromBech32(msg.Sender) diff --git a/x/nft/keeper/msg_server_test.go b/x/nft/keeper/msg_server_test.go new file mode 100644 index 000000000..f9f173575 --- /dev/null +++ b/x/nft/keeper/msg_server_test.go @@ -0,0 +1,110 @@ +package keeper_test + +import ( + "fmt" + + "github.com/cosmos/cosmos-sdk/x/nft" +) + +var ( + ExpClass = nft.Class{ + Id: testClassID, + Name: testClassName, + Symbol: testClassSymbol, + Description: testClassDescription, + Uri: testClassURI, + UriHash: testClassURIHash, + } + + ExpNFT = nft.NFT{ + ClassId: testClassID, + Id: testID, + Uri: testURI, + } +) + +func (s *TestSuite) TestSend() { + err := s.nftKeeper.SaveClass(s.ctx, ExpClass) + s.Require().NoError(err) + + actual, has := s.nftKeeper.GetClass(s.ctx, testClassID) + s.Require().True(has) + s.Require().EqualValues(ExpClass, actual) + + err = s.nftKeeper.Mint(s.ctx, ExpNFT, s.addrs[0]) + s.Require().NoError(err) + + expGenesis := &nft.GenesisState{ + Classes: []*nft.Class{&ExpClass}, + Entries: []*nft.Entry{{ + Owner: s.addrs[0].String(), + Nfts: []*nft.NFT{&ExpNFT}, + }}, + } + genesis := s.nftKeeper.ExportGenesis(s.ctx) + s.Require().Equal(expGenesis, genesis) + + testCases := []struct { + name string + req *nft.MsgSend + expErr bool + errMsg string + }{ + { + name: "invalid class id", + req: &nft.MsgSend{ + ClassId: "invalid ClassId", + Id: testID, + Sender: s.addrs[0].String(), + Receiver: s.addrs[1].String(), + }, + expErr: true, + errMsg: "unauthorized", + }, + { + name: "invalid nft id", + req: &nft.MsgSend{ + ClassId: testClassID, + Id: "invalid Id", + Sender: s.addrs[0].String(), + Receiver: s.addrs[1].String(), + }, + expErr: true, + errMsg: "unauthorized", + }, + { + name: "unauthorized sender", + req: &nft.MsgSend{ + ClassId: testClassID, + Id: testID, + Sender: s.addrs[1].String(), + Receiver: s.addrs[2].String(), + }, + expErr: true, + errMsg: fmt.Sprintf("%s is not the owner of nft %s", s.addrs[1].String(), testID), + }, + { + name: "valid transaction", + req: &nft.MsgSend{ + ClassId: testClassID, + Id: testID, + Sender: s.addrs[0].String(), + Receiver: s.addrs[1].String(), + }, + expErr: false, + errMsg: "", + }, + } + + for _, tc := range testCases { + s.Run(tc.name, func() { + _, err := s.nftKeeper.Send(s.ctx, tc.req) + if tc.expErr { + s.Require().Error(err) + s.Require().Contains(err.Error(), tc.errMsg) + } else { + s.Require().NoError(err) + } + }) + } +} diff --git a/x/nft/keys.go b/x/nft/keys.go index b3c11046e..fac6adb7a 100644 --- a/x/nft/keys.go +++ b/x/nft/keys.go @@ -1,7 +1,7 @@ package nft const ( - // ModuleName module name + // ModuleName defines the name of the nft module ModuleName = "nft" // StoreKey is the default store key for nft diff --git a/x/nft/msgs.go b/x/nft/msgs.go index 57926287b..0fdbd8749 100644 --- a/x/nft/msgs.go +++ b/x/nft/msgs.go @@ -2,6 +2,7 @@ package nft import ( "cosmossdk.io/errors" + sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" ) @@ -35,7 +36,7 @@ func (m MsgSend) ValidateBasic() error { return nil } -// GetSigners implements Msg +// GetSigners returns the expected signers for MsgSend. func (m MsgSend) GetSigners() []sdk.AccAddress { signer, _ := sdk.AccAddressFromBech32(m.Sender) return []sdk.AccAddress{signer} diff --git a/x/nft/query.pb.go b/x/nft/query.pb.go index a5ab3e80d..cc628b80c 100644 --- a/x/nft/query.pb.go +++ b/x/nft/query.pb.go @@ -31,8 +31,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package // QueryBalanceRequest is the request type for the Query/Balance RPC method type QueryBalanceRequest struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` } func (m *QueryBalanceRequest) Reset() { *m = QueryBalanceRequest{} } @@ -84,6 +86,7 @@ func (m *QueryBalanceRequest) GetOwner() string { // QueryBalanceResponse is the response type for the Query/Balance RPC method type QueryBalanceResponse struct { + // amount is the number of all NFTs of a given class owned by the owner Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"` } @@ -129,8 +132,10 @@ func (m *QueryBalanceResponse) GetAmount() uint64 { // QueryOwnerRequest is the request type for the Query/Owner RPC method type QueryOwnerRequest struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // id is a unique identifier of the NFT + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` } func (m *QueryOwnerRequest) Reset() { *m = QueryOwnerRequest{} } @@ -182,6 +187,7 @@ func (m *QueryOwnerRequest) GetId() string { // QueryOwnerResponse is the response type for the Query/Owner RPC method type QueryOwnerResponse struct { + // owner is the owner address of the nft Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"` } @@ -227,6 +233,7 @@ func (m *QueryOwnerResponse) GetOwner() string { // QuerySupplyRequest is the request type for the Query/Supply RPC method type QuerySupplyRequest struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` } @@ -272,6 +279,7 @@ func (m *QuerySupplyRequest) GetClassId() string { // QuerySupplyResponse is the response type for the Query/Supply RPC method type QuerySupplyResponse struct { + // amount is the number of all NFTs from the given class Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"` } @@ -317,8 +325,11 @@ func (m *QuerySupplyResponse) GetAmount() uint64 { // QueryNFTstRequest is the request type for the Query/NFTs RPC method type QueryNFTsRequest struct { - ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + // class_id associated with the nft + ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` + // owner is the owner address of the nft + Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"` + // pagination defines an optional pagination for the request. Pagination *query.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -378,7 +389,9 @@ func (m *QueryNFTsRequest) GetPagination() *query.PageRequest { // QueryNFTsResponse is the response type for the Query/NFTs RPC methods type QueryNFTsResponse struct { - Nfts []*NFT `protobuf:"bytes,1,rep,name=nfts,proto3" json:"nfts,omitempty"` + // NFT defines the NFT + Nfts []*NFT `protobuf:"bytes,1,rep,name=nfts,proto3" json:"nfts,omitempty"` + // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } @@ -431,8 +444,10 @@ func (m *QueryNFTsResponse) GetPagination() *query.PageResponse { // QueryNFTRequest is the request type for the Query/NFT RPC method type QueryNFTRequest struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` - Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` + // id is a unique identifier of the NFT + Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"` } func (m *QueryNFTRequest) Reset() { *m = QueryNFTRequest{} } @@ -484,6 +499,7 @@ func (m *QueryNFTRequest) GetId() string { // QueryNFTResponse is the response type for the Query/NFT RPC method type QueryNFTResponse struct { + // owner is the owner address of the nft Nft *NFT `protobuf:"bytes,1,opt,name=nft,proto3" json:"nft,omitempty"` } @@ -529,6 +545,7 @@ func (m *QueryNFTResponse) GetNft() *NFT { // QueryClassRequest is the request type for the Query/Class RPC method type QueryClassRequest struct { + // class_id associated with the nft ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"` } @@ -574,6 +591,7 @@ func (m *QueryClassRequest) GetClassId() string { // QueryClassResponse is the response type for the Query/Class RPC method type QueryClassResponse struct { + // class defines the class of the nft type. Class *Class `protobuf:"bytes,1,opt,name=class,proto3" json:"class,omitempty"` } @@ -665,7 +683,9 @@ func (m *QueryClassesRequest) GetPagination() *query.PageRequest { // QueryClassesResponse is the response type for the Query/Classes RPC method type QueryClassesResponse struct { - Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"` + // class defines the class of the nft type. + Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"` + // pagination defines the pagination in the response. Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"` } diff --git a/x/nft/simulation/decoder.go b/x/nft/simulation/decoder.go index 3af35a539..85eec43b7 100644 --- a/x/nft/simulation/decoder.go +++ b/x/nft/simulation/decoder.go @@ -11,7 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/nft/keeper" ) -// NewDecodeStore returns a decoder function closure that umarshals the KVPair's +// NewDecodeStore returns a decoder function closure that unmarshals the KVPair's // Value to the corresponding nft type. func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string { return func(kvA, kvB kv.Pair) string { diff --git a/x/nft/simulation/operations.go b/x/nft/simulation/operations.go index b05f1c25f..60e079cc0 100644 --- a/x/nft/simulation/operations.go +++ b/x/nft/simulation/operations.go @@ -119,6 +119,7 @@ func SimulateMsgSend( } } +// randNFT picks a random NFT from a class belonging to the specified owner(minter). func randNFT(ctx sdk.Context, r *rand.Rand, k keeper.Keeper, minter sdk.AccAddress) (nft.NFT, error) { c, err := randClass(ctx, r, k) if err != nil { @@ -141,6 +142,7 @@ func randNFT(ctx sdk.Context, r *rand.Rand, k keeper.Keeper, minter sdk.AccAddre return n, nil } +// randClass picks a random Class. func randClass(ctx sdk.Context, r *rand.Rand, k keeper.Keeper) (nft.Class, error) { classes := k.GetClasses(ctx) if len(classes) == 0 {