/
collection.go
140 lines (124 loc) · 4.41 KB
/
collection.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// Copyright (c) 2016-2021 Shanghai Bianjie AI Technology Inc. (licensed under the Apache License, Version 2.0)
// Modifications Copyright (c) 2021, CRO Protocol Labs ("Crypto.org") (licensed under the Apache License, Version 2.0)
package keeper
import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/cosmos/cosmos-sdk/store/prefix"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/crypto-org-chain/chain-main/v3/x/nft/exported"
"github.com/crypto-org-chain/chain-main/v3/x/nft/types"
)
// SetGenesisCollection saves all NFTs and returns an error if there already exists or any one of the owner's bech32
// account address is invalid
func (k Keeper) SetGenesisCollection(ctx sdk.Context, collection types.Collection) error {
for _, nft := range collection.NFTs {
if err := k.MintNFTUnverified(
ctx,
collection.Denom.Id,
nft.GetID(),
nft.GetName(),
nft.GetURI(),
nft.GetData(),
nft.GetOwner(),
); err != nil {
return err
}
}
return nil
}
// SetCollection saves all NFTs and returns an error if there already exists or any one of the owner's bech32 account
// address is invalid or any NFT's owner is not the creator of denomination
func (k Keeper) SetCollection(ctx sdk.Context, collection types.Collection, sender sdk.AccAddress) error {
for _, nft := range collection.NFTs {
if err := k.MintNFT(
ctx,
collection.Denom.Id,
nft.GetID(),
nft.GetName(),
nft.GetURI(),
nft.GetData(),
sender,
nft.GetOwner(),
); err != nil {
return err
}
}
return nil
}
// GetCollection returns the collection by the specified denom ID
func (k Keeper) GetCollection(ctx sdk.Context, denomID string) (types.Collection, error) {
denom, err := k.GetDenom(ctx, denomID)
if err != nil {
return types.Collection{}, sdkerrors.Wrapf(types.ErrInvalidDenom, "denomID %s not existed ", denomID)
}
nfts := k.GetNFTs(ctx, denomID)
return types.NewCollection(denom, nfts), nil
}
// GetPaginateCollection returns the collection by the specified denom ID
func (k Keeper) GetPaginateCollection(ctx sdk.Context, request *types.QueryCollectionRequest, denomID string) (types.Collection, *query.PageResponse, error) {
denom, err := k.GetDenom(ctx, denomID)
if err != nil {
return types.Collection{}, nil, sdkerrors.Wrapf(types.ErrInvalidDenom, "denomID %s not existed ", denomID)
}
var nfts []exported.NFT
store := ctx.KVStore(k.storeKey)
nftStore := prefix.NewStore(store, types.KeyNFT(denomID, ""))
pageRes, err := query.Paginate(nftStore, request.Pagination, func(key []byte, value []byte) error {
var baseNFT types.BaseNFT
k.cdc.MustUnmarshal(value, &baseNFT)
nfts = append(nfts, baseNFT)
return nil
})
if err != nil {
return types.Collection{}, nil, status.Errorf(codes.InvalidArgument, "paginate: %v", err)
}
return types.NewCollection(denom, nfts), pageRes, nil
}
// GetCollections returns all the collections
func (k Keeper) GetCollections(ctx sdk.Context) (cs []types.Collection) {
for _, denom := range k.GetDenoms(ctx) {
nfts := k.GetNFTs(ctx, denom.Id)
cs = append(cs, types.NewCollection(denom, nfts))
}
return cs
}
// GetTotalSupply returns the number of NFTs by the specified denom ID
func (k Keeper) GetTotalSupply(ctx sdk.Context, denomID string) uint64 {
store := ctx.KVStore(k.storeKey)
bz := store.Get(types.KeyCollection(denomID))
if len(bz) == 0 {
return 0
}
return types.MustUnMarshalSupply(k.cdc, bz)
}
// GetTotalSupplyOfOwner returns the amount of NFTs by the specified conditions
func (k Keeper) GetTotalSupplyOfOwner(ctx sdk.Context, id string, owner sdk.AccAddress) (supply uint64) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.KeyOwner(owner, id, ""))
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
supply++
}
return supply
}
func (k Keeper) increaseSupply(ctx sdk.Context, denomID string) {
supply := k.GetTotalSupply(ctx, denomID)
supply++
store := ctx.KVStore(k.storeKey)
bz := types.MustMarshalSupply(k.cdc, supply)
store.Set(types.KeyCollection(denomID), bz)
}
func (k Keeper) decreaseSupply(ctx sdk.Context, denomID string) {
supply := k.GetTotalSupply(ctx, denomID)
supply--
store := ctx.KVStore(k.storeKey)
if supply == 0 {
store.Delete(types.KeyCollection(denomID))
return
}
bz := types.MustMarshalSupply(k.cdc, supply)
store.Set(types.KeyCollection(denomID), bz)
}