-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
23f707a
commit cdc21dd
Showing
7 changed files
with
4,542 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
syntax = "proto3"; | ||
package onft.v1; | ||
|
||
import "google/protobuf/any.proto"; | ||
|
||
option go_package = "github.com/ODIN-PROTOCOL/odin-core/x/onft/types"; | ||
|
||
// Class defines the class of the nft type. | ||
message Class { | ||
// id defines the unique identifier of the NFT classification, similar to the contract address of ERC721 | ||
string id = 1; | ||
|
||
// name defines the human-readable name of the NFT classification. Optional | ||
string name = 2; | ||
|
||
// symbol is an abbreviated name for nft classification. Optional | ||
string symbol = 3; | ||
|
||
// description is a brief description of nft classification. Optional | ||
string description = 4; | ||
|
||
// uri for the class metadata stored off chain. It can define schema for Class and NFT `Data` attributes. Optional | ||
string uri = 5; | ||
|
||
// uri_hash is a hash of the document pointed by uri. Optional | ||
string uri_hash = 6; | ||
|
||
// data is the app specific metadata of the NFT class. Optional | ||
google.protobuf.Any data = 7; | ||
|
||
// owner is the owner address of the following nft class | ||
string owner = 8; | ||
} | ||
|
||
// NFT defines the NFT. | ||
message NFT { | ||
// class_id associated with the NFT, similar to the contract address of ERC721 | ||
string class_id = 1; | ||
|
||
// id is a unique identifier of the NFT | ||
string id = 2; | ||
|
||
// uri for the NFT metadata stored off chain | ||
string uri = 3; | ||
|
||
// uri_hash is a hash of the document pointed by uri | ||
string uri_hash = 4; | ||
|
||
// owner is the owner address of the following nft | ||
string owner = 5; | ||
|
||
// data is an app specific data of the NFT. Optional | ||
google.protobuf.Any data = 10; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
syntax = "proto3"; | ||
package onft.v1; | ||
|
||
option go_package = "github.com/ODIN-PROTOCOL/odin-core/x/onft/types"; | ||
|
||
import "google/api/annotations.proto"; | ||
import "cosmos/base/query/v1beta1/pagination.proto"; | ||
import "onft/v1/onft.proto"; | ||
|
||
// Query defines the gRPC querier service. | ||
service Query { | ||
// ClassOwner queries the owner of the NFT class | ||
rpc ClassOwner(QueryClassOwnerRequest) returns (QueryClassOwnerResponse) { | ||
option (google.api.http).get = "/onft/v1/class/{class_id}/owner"; | ||
} | ||
|
||
// NFTs queries all NFTs with owners of a given class or owner,choose at least one of the two, | ||
// similar to tokenByIndex in ERC721Enumerable | ||
rpc NFTs(QueryNFTsRequest) returns (QueryNFTsResponse) { | ||
option (google.api.http).get = "/onft/v1/nfts"; | ||
} | ||
|
||
// NFT queries an NFT with owner based on its class and id | ||
rpc NFT(QueryNFTRequest) returns (QueryNFTResponse) { | ||
option (google.api.http).get = "/onft/v1/nfts/{class_id}/{id}"; | ||
} | ||
|
||
// Class queries an NFT class based on its id with class owner | ||
rpc Class(QueryClassRequest) returns (QueryClassResponse) { | ||
option (google.api.http).get = "/onft/v1/classes/{class_id}"; | ||
} | ||
|
||
// Classes queries all NFT classes with owners | ||
rpc Classes(QueryClassesRequest) returns (QueryClassesResponse) { | ||
option (google.api.http).get = "/onft/v1/classes"; | ||
} | ||
} | ||
|
||
// QueryClassOwnerRequest is the request type for the Query/Owner RPC method | ||
message QueryClassOwnerRequest { | ||
// class_id associated with nft collection | ||
string class_id = 1; | ||
} | ||
|
||
// QueryClassOwnerResponse is the response type for the Query/Owner RPC method | ||
message QueryClassOwnerResponse { | ||
// owner is the owner address of the nft class | ||
string owner = 1; | ||
} | ||
|
||
// QueryNFTstRequest is the request type for the Query/NFTs RPC method | ||
message QueryNFTsRequest { | ||
// 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 { | ||
// NFT defines the NFT | ||
repeated 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; | ||
|
||
// 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 | ||
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. | ||
Class class = 1; | ||
} | ||
|
||
// QueryClassesRequest is the request type for the Query/Classes RPC method | ||
message QueryClassesRequest { | ||
// pagination defines an optional pagination for the request. | ||
cosmos.base.query.v1beta1.PageRequest pagination = 1; | ||
} | ||
|
||
// QueryClassesResponse is the response type for the Query/Classes RPC method | ||
message QueryClassesResponse { | ||
// class defines the class of the nft type. | ||
repeated Class classes = 1; | ||
|
||
// pagination defines the pagination in the response. | ||
cosmos.base.query.v1beta1.PageResponse pagination = 2; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
package keeper | ||
|
||
import ( | ||
"context" | ||
|
||
"cosmossdk.io/x/nft" | ||
onfttypes "github.com/ODIN-PROTOCOL/odin-core/x/onft/types" | ||
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" | ||
) | ||
|
||
var _ onfttypes.QueryServer = Keeper{} | ||
|
||
func (k Keeper) ClassOwner(ctx context.Context, r *onfttypes.QueryClassOwnerRequest) (*onfttypes.QueryClassOwnerResponse, error) { | ||
if r == nil { | ||
return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") | ||
} | ||
|
||
if len(r.ClassId) == 0 { | ||
return nil, nft.ErrEmptyClassID | ||
} | ||
|
||
owner, err := k.ClassOwners.Get(ctx, r.ClassId) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
ownerStr, err := k.addressCodec.BytesToString(owner) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &onfttypes.QueryClassOwnerResponse{Owner: ownerStr}, nil | ||
} | ||
|
||
func (k Keeper) NFTs(ctx context.Context, r *onfttypes.QueryNFTsRequest) (*onfttypes.QueryNFTsResponse, error) { | ||
if r == nil { | ||
return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") | ||
} | ||
|
||
nfts, err := k.nftKeeper.NFTs(ctx, &nft.QueryNFTsRequest{Pagination: r.Pagination}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
nftsOwners := make([]*onfttypes.NFT, len(nfts.Nfts)) | ||
for i, n := range nfts.Nfts { | ||
ownerStr := "" | ||
owner := k.nftKeeper.GetOwner(ctx, n.ClassId, n.Id) | ||
if !owner.Empty() { | ||
ownerStr, _ = k.addressCodec.BytesToString(owner) | ||
} | ||
|
||
nftsOwners[i] = &onfttypes.NFT{ | ||
Id: n.Id, | ||
ClassId: n.ClassId, | ||
Uri: n.Uri, | ||
UriHash: n.UriHash, | ||
Data: n.Data, | ||
Owner: ownerStr, | ||
} | ||
} | ||
|
||
return &onfttypes.QueryNFTsResponse{ | ||
Nfts: nftsOwners, | ||
Pagination: nfts.Pagination, | ||
}, nil | ||
} | ||
|
||
func (k Keeper) NFT(ctx context.Context, r *onfttypes.QueryNFTRequest) (*onfttypes.QueryNFTResponse, error) { | ||
if r == nil { | ||
return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") | ||
} | ||
|
||
if len(r.ClassId) == 0 { | ||
return nil, nft.ErrEmptyClassID | ||
} | ||
if len(r.Id) == 0 { | ||
return nil, nft.ErrEmptyNFTID | ||
} | ||
|
||
n, has := k.nftKeeper.GetNFT(ctx, r.ClassId, r.Id) | ||
if !has { | ||
return nil, nft.ErrNFTNotExists.Wrapf("not found nft: class: %s, id: %s", r.ClassId, r.Id) | ||
} | ||
|
||
owner := k.nftKeeper.GetOwner(ctx, r.ClassId, r.Id) | ||
ownerStr, err := k.addressCodec.BytesToString(owner) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp := &onfttypes.QueryNFTResponse{ | ||
Nft: &onfttypes.NFT{ | ||
ClassId: n.ClassId, | ||
Id: n.Id, | ||
Uri: n.Uri, | ||
UriHash: n.UriHash, | ||
Owner: ownerStr, | ||
Data: n.Data, | ||
}, | ||
} | ||
|
||
return resp, nil | ||
} | ||
|
||
func (k Keeper) Class(ctx context.Context, r *onfttypes.QueryClassRequest) (*onfttypes.QueryClassResponse, error) { | ||
if r == nil { | ||
return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") | ||
} | ||
|
||
if len(r.ClassId) == 0 { | ||
return nil, nft.ErrEmptyClassID | ||
} | ||
|
||
class, has := k.nftKeeper.GetClass(ctx, r.ClassId) | ||
if !has { | ||
return nil, nft.ErrClassNotExists.Wrapf("not found class: %s", r.ClassId) | ||
} | ||
|
||
owner, err := k.ClassOwners.Get(ctx, r.ClassId) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
ownerStr, err := k.addressCodec.BytesToString(owner) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
resp := &onfttypes.QueryClassResponse{ | ||
Class: &onfttypes.Class{ | ||
Id: class.Id, | ||
Name: class.Name, | ||
Symbol: class.Symbol, | ||
Description: class.Description, | ||
Uri: class.Uri, | ||
UriHash: class.UriHash, | ||
Data: class.Data, | ||
Owner: ownerStr, | ||
}, | ||
} | ||
|
||
return resp, nil | ||
} | ||
|
||
func (k Keeper) Classes(ctx context.Context, r *onfttypes.QueryClassesRequest) (*onfttypes.QueryClassesResponse, error) { | ||
if r == nil { | ||
return nil, sdkerrors.ErrInvalidRequest.Wrap("empty request") | ||
} | ||
|
||
classes, err := k.nftKeeper.Classes(ctx, &nft.QueryClassesRequest{Pagination: r.Pagination}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
classesOwners := make([]*onfttypes.Class, len(classes.Classes)) | ||
for i, class := range classes.Classes { | ||
ownerStr := "" | ||
owner, err := k.ClassOwners.Get(ctx, class.Id) | ||
if err == nil { | ||
ownerStr, _ = k.addressCodec.BytesToString(owner) | ||
} | ||
|
||
classesOwners[i] = &onfttypes.Class{ | ||
Id: class.Id, | ||
Name: class.Name, | ||
Symbol: class.Symbol, | ||
Description: class.Description, | ||
Uri: class.Uri, | ||
UriHash: class.UriHash, | ||
Data: class.Data, | ||
Owner: ownerStr, | ||
} | ||
} | ||
|
||
return &onfttypes.QueryClassesResponse{ | ||
Classes: classesOwners, | ||
Pagination: classes.Pagination, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.