parent
58a167d702
commit
11bbeede3c
|
@ -1739,9 +1739,13 @@ type EventSend struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"`
|
// class_id associated with the nft
|
||||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"`
|
||||||
Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,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"`
|
Receiver string `protobuf:"bytes,4,opt,name=receiver,proto3" json:"receiver,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1799,9 +1803,12 @@ type EventMint struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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
|
||||||
Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"`
|
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() {
|
func (x *EventMint) Reset() {
|
||||||
|
@ -1851,9 +1858,12 @@ type EventBurn struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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
|
||||||
Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"`
|
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() {
|
func (x *EventBurn) Reset() {
|
||||||
|
|
|
@ -1223,6 +1223,7 @@ type GenesisState struct {
|
||||||
|
|
||||||
// class defines the class of the nft type.
|
// class defines the class of the nft type.
|
||||||
Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"`
|
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"`
|
Entries []*Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6567,8 +6567,10 @@ type QueryBalanceRequest struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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() {
|
func (x *QueryBalanceRequest) Reset() {
|
||||||
|
@ -6611,6 +6613,7 @@ type QueryBalanceResponse struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6647,8 +6650,10 @@ type QueryOwnerRequest struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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() {
|
func (x *QueryOwnerRequest) Reset() {
|
||||||
|
@ -6691,6 +6696,7 @@ type QueryOwnerResponse struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// owner is the owner address of the nft
|
||||||
Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"`
|
Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6727,6 +6733,7 @@ type QuerySupplyRequest struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
Amount uint64 `protobuf:"varint,1,opt,name=amount,proto3" json:"amount,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6799,8 +6807,11 @@ type QueryNFTsRequest struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"`
|
// class_id associated with the nft
|
||||||
Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"`
|
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"`
|
Pagination *v1beta1.PageRequest `protobuf:"bytes,3,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6851,7 +6862,9 @@ type QueryNFTsResponse struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6895,8 +6908,10 @@ type QueryNFTRequest struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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() {
|
func (x *QueryNFTRequest) Reset() {
|
||||||
|
@ -6939,6 +6954,7 @@ type QueryNFTResponse struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// owner is the owner address of the nft
|
||||||
Nft *NFT `protobuf:"bytes,1,opt,name=nft,proto3" json:"nft,omitempty"`
|
Nft *NFT `protobuf:"bytes,1,opt,name=nft,proto3" json:"nft,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6975,6 +6991,7 @@ type QueryClassRequest struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
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
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
unknownFields protoimpl.UnknownFields
|
||||||
|
|
||||||
|
// class defines the class of the nft type.
|
||||||
Class *Class `protobuf:"bytes,1,opt,name=class,proto3" json:"class,omitempty"`
|
Class *Class `protobuf:"bytes,1,opt,name=class,proto3" json:"class,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7084,7 +7102,9 @@ type QueryClassesResponse struct {
|
||||||
sizeCache protoimpl.SizeCache
|
sizeCache protoimpl.SizeCache
|
||||||
unknownFields protoimpl.UnknownFields
|
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"`
|
Pagination *v1beta1.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,13 +32,13 @@ message MsgVerifyInvariant {
|
||||||
option (gogoproto.goproto_getters) = false;
|
option (gogoproto.goproto_getters) = false;
|
||||||
|
|
||||||
// sender is the account address of private key to send coins to fee collector account.
|
// 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.
|
// name of the invariant module.
|
||||||
string invariant_module_name = 2;
|
string invariant_module_name = 2;
|
||||||
|
|
||||||
// invariant_route is the msg's invariant route.
|
// invariant_route is the msg's invariant route.
|
||||||
string invariant_route = 3;
|
string invariant_route = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type.
|
// MsgVerifyInvariantResponse defines the Msg/VerifyInvariant response type.
|
||||||
|
|
|
@ -5,22 +5,39 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/nft";
|
||||||
|
|
||||||
// EventSend is emitted on Msg/Send
|
// EventSend is emitted on Msg/Send
|
||||||
message EventSend {
|
message EventSend {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
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;
|
string receiver = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
// EventMint is emitted on Mint
|
// EventMint is emitted on Mint
|
||||||
message EventMint {
|
message EventMint {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
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
|
// EventBurn is emitted on Burn
|
||||||
message EventBurn {
|
message EventBurn {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ option go_package = "github.com/cosmos/cosmos-sdk/x/nft";
|
||||||
message GenesisState {
|
message GenesisState {
|
||||||
// class defines the class of the nft type.
|
// class defines the class of the nft type.
|
||||||
repeated cosmos.nft.v1beta1.Class classes = 1;
|
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
|
// Entry Defines all nft owned by a person
|
||||||
|
|
|
@ -48,67 +48,91 @@ service Query {
|
||||||
|
|
||||||
// QueryBalanceRequest is the request type for the Query/Balance RPC method
|
// QueryBalanceRequest is the request type for the Query/Balance RPC method
|
||||||
message QueryBalanceRequest {
|
message QueryBalanceRequest {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
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
|
// QueryBalanceResponse is the response type for the Query/Balance RPC method
|
||||||
message QueryBalanceResponse {
|
message QueryBalanceResponse {
|
||||||
|
// amount is the number of all NFTs of a given class owned by the owner
|
||||||
uint64 amount = 1;
|
uint64 amount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryOwnerRequest is the request type for the Query/Owner RPC method
|
// QueryOwnerRequest is the request type for the Query/Owner RPC method
|
||||||
message QueryOwnerRequest {
|
message QueryOwnerRequest {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
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
|
// QueryOwnerResponse is the response type for the Query/Owner RPC method
|
||||||
message QueryOwnerResponse {
|
message QueryOwnerResponse {
|
||||||
|
// owner is the owner address of the nft
|
||||||
string owner = 1;
|
string owner = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuerySupplyRequest is the request type for the Query/Supply RPC method
|
// QuerySupplyRequest is the request type for the Query/Supply RPC method
|
||||||
message QuerySupplyRequest {
|
message QuerySupplyRequest {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
string class_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QuerySupplyResponse is the response type for the Query/Supply RPC method
|
// QuerySupplyResponse is the response type for the Query/Supply RPC method
|
||||||
message QuerySupplyResponse {
|
message QuerySupplyResponse {
|
||||||
|
// amount is the number of all NFTs from the given class
|
||||||
uint64 amount = 1;
|
uint64 amount = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryNFTstRequest is the request type for the Query/NFTs RPC method
|
// QueryNFTstRequest is the request type for the Query/NFTs RPC method
|
||||||
message QueryNFTsRequest {
|
message QueryNFTsRequest {
|
||||||
string class_id = 1;
|
// class_id associated with the nft
|
||||||
string owner = 2;
|
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;
|
cosmos.base.query.v1beta1.PageRequest pagination = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryNFTsResponse is the response type for the Query/NFTs RPC methods
|
// QueryNFTsResponse is the response type for the Query/NFTs RPC methods
|
||||||
message QueryNFTsResponse {
|
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;
|
cosmos.base.query.v1beta1.PageResponse pagination = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryNFTRequest is the request type for the Query/NFT RPC method
|
// QueryNFTRequest is the request type for the Query/NFT RPC method
|
||||||
message QueryNFTRequest {
|
message QueryNFTRequest {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
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
|
// QueryNFTResponse is the response type for the Query/NFT RPC method
|
||||||
message QueryNFTResponse {
|
message QueryNFTResponse {
|
||||||
|
// owner is the owner address of the nft
|
||||||
cosmos.nft.v1beta1.NFT nft = 1;
|
cosmos.nft.v1beta1.NFT nft = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryClassRequest is the request type for the Query/Class RPC method
|
// QueryClassRequest is the request type for the Query/Class RPC method
|
||||||
message QueryClassRequest {
|
message QueryClassRequest {
|
||||||
|
// class_id associated with the nft
|
||||||
string class_id = 1;
|
string class_id = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryClassResponse is the response type for the Query/Class RPC method
|
// QueryClassResponse is the response type for the Query/Class RPC method
|
||||||
message QueryClassResponse {
|
message QueryClassResponse {
|
||||||
|
// class defines the class of the nft type.
|
||||||
cosmos.nft.v1beta1.Class class = 1;
|
cosmos.nft.v1beta1.Class class = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,6 +144,9 @@ message QueryClassesRequest {
|
||||||
|
|
||||||
// QueryClassesResponse is the response type for the Query/Classes RPC method
|
// QueryClassesResponse is the response type for the Query/Classes RPC method
|
||||||
message QueryClassesResponse {
|
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;
|
cosmos.base.query.v1beta1.PageResponse pagination = 2;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,13 @@
|
||||||
package cli_test
|
package cli_test
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
|
|
||||||
|
"github.com/cosmos/cosmos-sdk/client"
|
||||||
"github.com/cosmos/cosmos-sdk/client/flags"
|
"github.com/cosmos/cosmos-sdk/client/flags"
|
||||||
|
svrcmd "github.com/cosmos/cosmos-sdk/server/cmd"
|
||||||
"github.com/cosmos/cosmos-sdk/testutil"
|
"github.com/cosmos/cosmos-sdk/testutil"
|
||||||
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
clitestutil "github.com/cosmos/cosmos-sdk/testutil/cli"
|
||||||
"github.com/cosmos/cosmos-sdk/x/nft"
|
"github.com/cosmos/cosmos-sdk/x/nft"
|
||||||
|
@ -12,111 +16,119 @@ import (
|
||||||
|
|
||||||
func (s *CLITestSuite) TestQueryClass() {
|
func (s *CLITestSuite) TestQueryClass() {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args struct {
|
args []string
|
||||||
ClassID string
|
expCmdOutput string
|
||||||
}
|
|
||||||
expectErr bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid case",
|
name: "json output",
|
||||||
args: struct {
|
args: []string{testClassID, fmt.Sprintf("--%s=json", flags.FlagOutput)},
|
||||||
ClassID string
|
expCmdOutput: `[kitty --output=json]`,
|
||||||
}{
|
},
|
||||||
ClassID: testClassID,
|
{
|
||||||
},
|
name: "text output",
|
||||||
expectErr: false,
|
args: []string{testClassID, fmt.Sprintf("--%s=text", flags.FlagOutput)},
|
||||||
|
expCmdOutput: `[kitty --output=text]`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
cmd := cli.GetCmdQueryClass()
|
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 {
|
ctx := svrcmd.CreateExecuteContext(context.Background())
|
||||||
s.Require().Error(err)
|
|
||||||
} else {
|
cmd.SetOut(io.Discard)
|
||||||
s.Require().NoError(err)
|
s.Require().NotNil(cmd)
|
||||||
var result nft.QueryClassResponse
|
|
||||||
err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)
|
cmd.SetContext(ctx)
|
||||||
s.Require().NoError(err)
|
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() {
|
func (s *CLITestSuite) TestQueryClasses() {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
expectErr bool
|
flagArgs []string
|
||||||
|
expCmdOutput string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "no params",
|
name: "json output",
|
||||||
expectErr: false,
|
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 {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
cmd := cli.GetCmdQueryClasses()
|
cmd := cli.GetCmdQueryClasses()
|
||||||
var args []string
|
ctx := svrcmd.CreateExecuteContext(context.Background())
|
||||||
args = append(args, fmt.Sprintf("--%s=json", flags.FlagOutput))
|
|
||||||
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
cmd.SetOut(io.Discard)
|
||||||
if tc.expectErr {
|
s.Require().NotNil(cmd)
|
||||||
s.Require().Error(err)
|
|
||||||
} else {
|
cmd.SetContext(ctx)
|
||||||
s.Require().NoError(err)
|
cmd.SetArgs(tc.flagArgs)
|
||||||
var result nft.QueryClassesResponse
|
s.Require().NoError(client.SetCmdClientContextHandler(s.baseCtx, cmd))
|
||||||
err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)
|
|
||||||
s.Require().NoError(err)
|
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() {
|
func (s *CLITestSuite) TestQueryNFT() {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args struct {
|
args []string
|
||||||
ClassID string
|
expCmdOutput string
|
||||||
ID string
|
|
||||||
}
|
|
||||||
expectErr bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid case",
|
name: "json output",
|
||||||
args: struct {
|
args: []string{testClassID, testID, fmt.Sprintf("--%s=json", flags.FlagOutput)},
|
||||||
ClassID string
|
expCmdOutput: `[kitty kitty1 --output=json]`,
|
||||||
ID string
|
},
|
||||||
}{
|
{
|
||||||
ClassID: testClassID,
|
name: "text output",
|
||||||
ID: testID,
|
args: []string{testClassID, testID, fmt.Sprintf("--%s=text", flags.FlagOutput)},
|
||||||
},
|
expCmdOutput: `[kitty kitty1 --output=text]`,
|
||||||
expectErr: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
cmd := cli.GetCmdQueryNFT()
|
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)
|
ctx := svrcmd.CreateExecuteContext(context.Background())
|
||||||
if tc.expectErr {
|
|
||||||
s.Require().Error(err)
|
cmd.SetOut(io.Discard)
|
||||||
} else {
|
s.Require().NotNil(cmd)
|
||||||
s.Require().NoError(err)
|
|
||||||
var result nft.QueryNFTResponse
|
cmd.SetContext(ctx)
|
||||||
err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)
|
cmd.SetArgs(tc.args)
|
||||||
s.Require().NoError(err)
|
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
|
Owner string
|
||||||
}
|
}
|
||||||
expectErr bool
|
expectErr bool
|
||||||
|
expErrMsg string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "empty class id and owner",
|
name: "empty class id and owner",
|
||||||
|
@ -139,6 +152,7 @@ func (s *CLITestSuite) TestQueryNFTs() {
|
||||||
Owner string
|
Owner string
|
||||||
}{},
|
}{},
|
||||||
expectErr: true,
|
expectErr: true,
|
||||||
|
expErrMsg: "must provide at least one of classID or owner",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "valid case",
|
name: "valid case",
|
||||||
|
@ -164,6 +178,7 @@ func (s *CLITestSuite) TestQueryNFTs() {
|
||||||
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
s.Require().Error(err)
|
s.Require().Error(err)
|
||||||
|
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||||
} else {
|
} else {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
var result nft.QueryNFTsResponse
|
var result nft.QueryNFTsResponse
|
||||||
|
@ -176,43 +191,40 @@ func (s *CLITestSuite) TestQueryNFTs() {
|
||||||
|
|
||||||
func (s *CLITestSuite) TestQueryOwner() {
|
func (s *CLITestSuite) TestQueryOwner() {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args struct {
|
args []string
|
||||||
ClassID string
|
expCmdOutput string
|
||||||
ID string
|
|
||||||
}
|
|
||||||
expectErr bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid case",
|
name: "json output",
|
||||||
args: struct {
|
args: []string{testClassID, testID, fmt.Sprintf("--%s=json", flags.FlagOutput)},
|
||||||
ClassID string
|
expCmdOutput: `[kitty kitty1 --output=json]`,
|
||||||
ID string
|
},
|
||||||
}{
|
{
|
||||||
ClassID: testClassID,
|
name: "text output",
|
||||||
ID: testID,
|
args: []string{testClassID, testID, fmt.Sprintf("--%s=text", flags.FlagOutput)},
|
||||||
},
|
expCmdOutput: `[kitty kitty1 --output=text]`,
|
||||||
expectErr: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
cmd := cli.GetCmdQueryOwner()
|
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)
|
ctx := svrcmd.CreateExecuteContext(context.Background())
|
||||||
if tc.expectErr {
|
|
||||||
s.Require().Error(err)
|
cmd.SetOut(io.Discard)
|
||||||
} else {
|
s.Require().NotNil(cmd)
|
||||||
s.Require().NoError(err)
|
|
||||||
var result nft.QueryOwnerResponse
|
cmd.SetContext(ctx)
|
||||||
err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)
|
cmd.SetArgs(tc.args)
|
||||||
s.Require().NoError(err)
|
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)
|
accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args struct {
|
args []string
|
||||||
ClassID string
|
expCmdOutput string
|
||||||
Owner string
|
|
||||||
}
|
|
||||||
expectErr bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid case",
|
name: "json output",
|
||||||
args: struct {
|
args: []string{accounts[0].Address.String(), testClassID, fmt.Sprintf("--%s=json", flags.FlagOutput)},
|
||||||
ClassID string
|
expCmdOutput: fmt.Sprintf("%s kitty --output=json", accounts[0].Address.String()),
|
||||||
Owner string
|
},
|
||||||
}{
|
{
|
||||||
ClassID: testClassID,
|
name: "text output",
|
||||||
Owner: accounts[0].Address.String(),
|
args: []string{accounts[0].Address.String(), testClassID, fmt.Sprintf("--%s=text", flags.FlagOutput)},
|
||||||
},
|
expCmdOutput: fmt.Sprintf("%s kitty --output=text", accounts[0].Address.String()),
|
||||||
expectErr: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
cmd := cli.GetCmdQueryBalance()
|
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)
|
ctx := svrcmd.CreateExecuteContext(context.Background())
|
||||||
if tc.expectErr {
|
|
||||||
s.Require().Error(err)
|
cmd.SetOut(io.Discard)
|
||||||
} else {
|
s.Require().NotNil(cmd)
|
||||||
s.Require().NoError(err)
|
|
||||||
var result nft.QueryBalanceResponse
|
cmd.SetContext(ctx)
|
||||||
err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)
|
cmd.SetArgs(tc.args)
|
||||||
s.Require().NoError(err)
|
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() {
|
func (s *CLITestSuite) TestQuerySupply() {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
args struct {
|
args []string
|
||||||
ClassID string
|
expCmdOutput string
|
||||||
}
|
|
||||||
expectErr bool
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "valid case",
|
name: "valid case",
|
||||||
args: struct {
|
args: []string{testClassID, fmt.Sprintf("--%s=json", flags.FlagOutput)},
|
||||||
ClassID string
|
expCmdOutput: `[kitty --output=json]`,
|
||||||
}{
|
|
||||||
ClassID: testClassID,
|
|
||||||
},
|
|
||||||
expectErr: false,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
cmd := cli.GetCmdQuerySupply()
|
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)
|
ctx := svrcmd.CreateExecuteContext(context.Background())
|
||||||
if tc.expectErr {
|
|
||||||
s.Require().Error(err)
|
cmd.SetOut(io.Discard)
|
||||||
} else {
|
s.Require().NotNil(cmd)
|
||||||
s.Require().NoError(err)
|
|
||||||
var result nft.QuerySupplyResponse
|
cmd.SetContext(ctx)
|
||||||
err = s.clientCtx.Codec.UnmarshalJSON(out.Bytes(), &result)
|
cmd.SetArgs(tc.args)
|
||||||
s.Require().NoError(err)
|
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)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ func GetTxCmd() *cobra.Command {
|
||||||
return nftTxCmd
|
return nftTxCmd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewCmdSend creates a CLI command for MsgSend.
|
||||||
func NewCmdSend() *cobra.Command {
|
func NewCmdSend() *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "send [class-id] [nft-id] [receiver] --from [sender]",
|
Use: "send [class-id] [nft-id] [receiver] --from [sender]",
|
||||||
|
|
|
@ -126,7 +126,7 @@ func (s *CLITestSuite) SetupSuite() {
|
||||||
func (s *CLITestSuite) TestCLITxSend() {
|
func (s *CLITestSuite) TestCLITxSend() {
|
||||||
accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
accounts := testutil.CreateKeyringAccounts(s.T(), s.kr, 1)
|
||||||
|
|
||||||
args := []string{
|
extraArgs := []string{
|
||||||
fmt.Sprintf("--%s=%s", flags.FlagFrom, OwnerName),
|
fmt.Sprintf("--%s=%s", flags.FlagFrom, OwnerName),
|
||||||
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
fmt.Sprintf("--%s=true", flags.FlagSkipConfirmation),
|
||||||
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
fmt.Sprintf("--%s=%s", flags.FlagBroadcastMode, flags.BroadcastSync),
|
||||||
|
@ -138,7 +138,41 @@ func (s *CLITestSuite) TestCLITxSend() {
|
||||||
args []string
|
args []string
|
||||||
expectedCode uint32
|
expectedCode uint32
|
||||||
expectErr bool
|
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",
|
"valid transaction",
|
||||||
[]string{
|
[]string{
|
||||||
|
@ -148,13 +182,14 @@ func (s *CLITestSuite) TestCLITxSend() {
|
||||||
},
|
},
|
||||||
0,
|
0,
|
||||||
false,
|
false,
|
||||||
|
"",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
tc := tc
|
tc := tc
|
||||||
s.Run(tc.name, func() {
|
s.Run(tc.name, func() {
|
||||||
args = append(args, tc.args...)
|
args := append(tc.args, extraArgs...)
|
||||||
cmd := cli.NewCmdSend()
|
cmd := cli.NewCmdSend()
|
||||||
cmd.SetContext(s.ctx)
|
cmd.SetContext(s.ctx)
|
||||||
cmd.SetArgs(args)
|
cmd.SetArgs(args)
|
||||||
|
@ -164,6 +199,7 @@ func (s *CLITestSuite) TestCLITxSend() {
|
||||||
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
out, err := clitestutil.ExecTestCLICmd(s.clientCtx, cmd, args)
|
||||||
if tc.expectErr {
|
if tc.expectErr {
|
||||||
s.Require().Error(err)
|
s.Require().Error(err)
|
||||||
|
s.Require().Contains(err.Error(), tc.expErrMsg)
|
||||||
} else {
|
} else {
|
||||||
var txResp sdk.TxResponse
|
var txResp sdk.TxResponse
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
"github.com/cosmos/cosmos-sdk/types/msgservice"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// RegisterInterfaces registers the interfaces types with the interface registry.
|
||||||
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
func RegisterInterfaces(registry types.InterfaceRegistry) {
|
||||||
registry.RegisterImplementations((*sdk.Msg)(nil),
|
registry.RegisterImplementations((*sdk.Msg)(nil),
|
||||||
&MsgSend{},
|
&MsgSend{},
|
||||||
|
|
|
@ -6,9 +6,9 @@ import (
|
||||||
|
|
||||||
// x/nft module sentinel errors
|
// x/nft module sentinel errors
|
||||||
var (
|
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")
|
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")
|
ErrNFTNotExists = errors.Register(ModuleName, 6, "nft does not exist")
|
||||||
ErrEmptyClassID = errors.Register(ModuleName, 7, "empty class id")
|
ErrEmptyClassID = errors.Register(ModuleName, 7, "empty class id")
|
||||||
ErrEmptyNFTID = errors.Register(ModuleName, 8, "empty nft id")
|
ErrEmptyNFTID = errors.Register(ModuleName, 8, "empty nft id")
|
||||||
|
|
|
@ -24,9 +24,13 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||||
|
|
||||||
// EventSend is emitted on Msg/Send
|
// EventSend is emitted on Msg/Send
|
||||||
type EventSend struct {
|
type EventSend struct {
|
||||||
ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"`
|
// class_id associated with the nft
|
||||||
Id string `protobuf:"bytes,2,opt,name=id,proto3" json:"id,omitempty"`
|
ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"`
|
||||||
Sender string `protobuf:"bytes,3,opt,name=sender,proto3" json:"sender,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"`
|
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
|
// EventMint is emitted on Mint
|
||||||
type EventMint struct {
|
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"`
|
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
|
||||||
Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"`
|
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{} }
|
func (m *EventMint) Reset() { *m = EventMint{} }
|
||||||
|
@ -154,9 +161,12 @@ func (m *EventMint) GetOwner() string {
|
||||||
|
|
||||||
// EventBurn is emitted on Burn
|
// EventBurn is emitted on Burn
|
||||||
type EventBurn struct {
|
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"`
|
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
|
||||||
Owner string `protobuf:"bytes,3,opt,name=owner,proto3" json:"owner,omitempty"`
|
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{} }
|
func (m *EventBurn) Reset() { *m = EventBurn{} }
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
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 {
|
func ValidateGenesis(data GenesisState) error {
|
||||||
for _, class := range data.Classes {
|
for _, class := range data.Classes {
|
||||||
if len(class.Id) == 0 {
|
if len(class.Id) == 0 {
|
||||||
|
@ -24,7 +24,7 @@ func ValidateGenesis(data GenesisState) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DefaultGenesisState - Return a default genesis state
|
// DefaultGenesisState - Returns a default genesis state
|
||||||
func DefaultGenesisState() *GenesisState {
|
func DefaultGenesisState() *GenesisState {
|
||||||
return &GenesisState{}
|
return &GenesisState{}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||||
type GenesisState struct {
|
type GenesisState struct {
|
||||||
// class defines the class of the nft type.
|
// class defines the class of the nft type.
|
||||||
Classes []*Class `protobuf:"bytes,1,rep,name=classes,proto3" json:"classes,omitempty"`
|
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"`
|
Entries []*Entry `protobuf:"bytes,2,rep,name=entries,proto3" json:"entries,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func (k Keeper) SaveClass(ctx sdk.Context, class nft.Class) error {
|
||||||
return nil
|
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 {
|
func (k Keeper) UpdateClass(ctx sdk.Context, class nft.Class) error {
|
||||||
if !k.HasClass(ctx, class.Id) {
|
if !k.HasClass(ctx, class.Id) {
|
||||||
return sdkerrors.Wrap(nft.ErrClassNotExists, class.Id)
|
return sdkerrors.Wrap(nft.ErrClassNotExists, class.Id)
|
||||||
|
|
|
@ -7,7 +7,8 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/nft"
|
"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) {
|
func (k Keeper) InitGenesis(ctx sdk.Context, data *nft.GenesisState) {
|
||||||
for _, class := range data.Classes {
|
for _, class := range data.Classes {
|
||||||
if err := k.SaveClass(ctx, *class); err != nil {
|
if err := k.SaveClass(ctx, *class); err != nil {
|
||||||
|
|
|
@ -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
|
// 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) {
|
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 {
|
if len(r.ClassId) == 0 {
|
||||||
return nil, nft.ErrEmptyClassID
|
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
|
// 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) {
|
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 {
|
if len(r.ClassId) == 0 {
|
||||||
return nil, nft.ErrEmptyClassID
|
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.
|
// 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) {
|
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 {
|
if len(r.ClassId) == 0 {
|
||||||
return nil, nft.ErrEmptyClassID
|
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
|
// 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) {
|
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 err error
|
||||||
var owner sdk.AccAddress
|
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.
|
// NFT return an NFT based on its class and id.
|
||||||
func (k Keeper) NFT(goCtx context.Context, r *nft.QueryNFTRequest) (*nft.QueryNFTResponse, error) {
|
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 {
|
if len(r.ClassId) == 0 {
|
||||||
return nil, nft.ErrEmptyClassID
|
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
|
// Class return an NFT class based on its id
|
||||||
func (k Keeper) Class(goCtx context.Context, r *nft.QueryClassRequest) (*nft.QueryClassResponse, error) {
|
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 {
|
if len(r.ClassId) == 0 {
|
||||||
return nil, nft.ErrEmptyClassID
|
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
|
// Classes return all NFT classes
|
||||||
func (k Keeper) Classes(goCtx context.Context, r *nft.QueryClassesRequest) (*nft.QueryClassesResponse, error) {
|
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)
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||||
store := ctx.KVStore(k.storeKey)
|
store := ctx.KVStore(k.storeKey)
|
||||||
classStore := prefix.NewStore(store, ClassKey)
|
classStore := prefix.NewStore(store, ClassKey)
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
|
|
||||||
var _ nft.MsgServer = Keeper{}
|
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) {
|
func (k Keeper) Send(goCtx context.Context, msg *nft.MsgSend) (*nft.MsgSendResponse, error) {
|
||||||
ctx := sdk.UnwrapSDKContext(goCtx)
|
ctx := sdk.UnwrapSDKContext(goCtx)
|
||||||
sender, err := sdk.AccAddressFromBech32(msg.Sender)
|
sender, err := sdk.AccAddressFromBech32(msg.Sender)
|
||||||
|
|
|
@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
package nft
|
package nft
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// ModuleName module name
|
// ModuleName defines the name of the nft module
|
||||||
ModuleName = "nft"
|
ModuleName = "nft"
|
||||||
|
|
||||||
// StoreKey is the default store key for nft
|
// StoreKey is the default store key for nft
|
||||||
|
|
|
@ -2,6 +2,7 @@ package nft
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cosmossdk.io/errors"
|
"cosmossdk.io/errors"
|
||||||
|
|
||||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
|
||||||
)
|
)
|
||||||
|
@ -35,7 +36,7 @@ func (m MsgSend) ValidateBasic() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSigners implements Msg
|
// GetSigners returns the expected signers for MsgSend.
|
||||||
func (m MsgSend) GetSigners() []sdk.AccAddress {
|
func (m MsgSend) GetSigners() []sdk.AccAddress {
|
||||||
signer, _ := sdk.AccAddressFromBech32(m.Sender)
|
signer, _ := sdk.AccAddressFromBech32(m.Sender)
|
||||||
return []sdk.AccAddress{signer}
|
return []sdk.AccAddress{signer}
|
||||||
|
|
|
@ -31,8 +31,10 @@ const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
|
||||||
|
|
||||||
// QueryBalanceRequest is the request type for the Query/Balance RPC method
|
// QueryBalanceRequest is the request type for the Query/Balance RPC method
|
||||||
type QueryBalanceRequest struct {
|
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"`
|
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{} }
|
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
|
// QueryBalanceResponse is the response type for the Query/Balance RPC method
|
||||||
type QueryBalanceResponse struct {
|
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"`
|
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
|
// QueryOwnerRequest is the request type for the Query/Owner RPC method
|
||||||
type QueryOwnerRequest struct {
|
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"`
|
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{} }
|
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
|
// QueryOwnerResponse is the response type for the Query/Owner RPC method
|
||||||
type QueryOwnerResponse struct {
|
type QueryOwnerResponse struct {
|
||||||
|
// owner is the owner address of the nft
|
||||||
Owner string `protobuf:"bytes,1,opt,name=owner,proto3" json:"owner,omitempty"`
|
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
|
// QuerySupplyRequest is the request type for the Query/Supply RPC method
|
||||||
type QuerySupplyRequest struct {
|
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"`
|
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
|
// QuerySupplyResponse is the response type for the Query/Supply RPC method
|
||||||
type QuerySupplyResponse struct {
|
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"`
|
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
|
// QueryNFTstRequest is the request type for the Query/NFTs RPC method
|
||||||
type QueryNFTsRequest struct {
|
type QueryNFTsRequest struct {
|
||||||
ClassId string `protobuf:"bytes,1,opt,name=class_id,json=classId,proto3" json:"class_id,omitempty"`
|
// class_id associated with the nft
|
||||||
Owner string `protobuf:"bytes,2,opt,name=owner,proto3" json:"owner,omitempty"`
|
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"`
|
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
|
// QueryNFTsResponse is the response type for the Query/NFTs RPC methods
|
||||||
type QueryNFTsResponse struct {
|
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"`
|
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
|
// QueryNFTRequest is the request type for the Query/NFT RPC method
|
||||||
type QueryNFTRequest struct {
|
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"`
|
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{} }
|
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
|
// QueryNFTResponse is the response type for the Query/NFT RPC method
|
||||||
type QueryNFTResponse struct {
|
type QueryNFTResponse struct {
|
||||||
|
// owner is the owner address of the nft
|
||||||
Nft *NFT `protobuf:"bytes,1,opt,name=nft,proto3" json:"nft,omitempty"`
|
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
|
// QueryClassRequest is the request type for the Query/Class RPC method
|
||||||
type QueryClassRequest struct {
|
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"`
|
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
|
// QueryClassResponse is the response type for the Query/Class RPC method
|
||||||
type QueryClassResponse struct {
|
type QueryClassResponse struct {
|
||||||
|
// class defines the class of the nft type.
|
||||||
Class *Class `protobuf:"bytes,1,opt,name=class,proto3" json:"class,omitempty"`
|
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
|
// QueryClassesResponse is the response type for the Query/Classes RPC method
|
||||||
type QueryClassesResponse struct {
|
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"`
|
Pagination *query.PageResponse `protobuf:"bytes,2,opt,name=pagination,proto3" json:"pagination,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"github.com/cosmos/cosmos-sdk/x/nft/keeper"
|
"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.
|
// Value to the corresponding nft type.
|
||||||
func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string {
|
func NewDecodeStore(cdc codec.Codec) func(kvA, kvB kv.Pair) string {
|
||||||
return func(kvA, kvB kv.Pair) string {
|
return func(kvA, kvB kv.Pair) string {
|
||||||
|
|
|
@ -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) {
|
func randNFT(ctx sdk.Context, r *rand.Rand, k keeper.Keeper, minter sdk.AccAddress) (nft.NFT, error) {
|
||||||
c, err := randClass(ctx, r, k)
|
c, err := randClass(ctx, r, k)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -141,6 +142,7 @@ func randNFT(ctx sdk.Context, r *rand.Rand, k keeper.Keeper, minter sdk.AccAddre
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// randClass picks a random Class.
|
||||||
func randClass(ctx sdk.Context, r *rand.Rand, k keeper.Keeper) (nft.Class, error) {
|
func randClass(ctx sdk.Context, r *rand.Rand, k keeper.Keeper) (nft.Class, error) {
|
||||||
classes := k.GetClasses(ctx)
|
classes := k.GetClasses(ctx)
|
||||||
if len(classes) == 0 {
|
if len(classes) == 0 {
|
||||||
|
|
Loading…
Reference in New Issue