/
owners.go
127 lines (110 loc) · 4.15 KB
/
owners.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
package keeper
import (
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/irisnet/modules/incubator/nft/internal/types"
)
// GetOwners returns all the Owners ID Collections
func (k Keeper) GetOwners(ctx sdk.Context) (owners []types.Owner) {
var foundOwners = make(map[string]bool)
k.IterateOwners(ctx,
func(owner types.Owner) (stop bool) {
if _, ok := foundOwners[owner.Address.String()]; !ok {
foundOwners[owner.Address.String()] = true
owners = append(owners, owner)
}
return false
},
)
return
}
// GetOwner gets all the ID Collections owned by an address
func (k Keeper) GetOwner(ctx sdk.Context, address sdk.AccAddress) (owner types.Owner) {
var idCollections []types.IDCollection
k.IterateIDCollections(ctx, types.GetOwnersKey(address),
func(_ sdk.AccAddress, idCollection types.IDCollection) (stop bool) {
idCollections = append(idCollections, idCollection)
return false
},
)
return types.NewOwner(address, idCollections...)
}
// GetOwnerByDenom gets the ID Collection owned by an address of a specific denom
func (k Keeper) GetOwnerByDenom(ctx sdk.Context, owner sdk.AccAddress, denom string) (idCollection types.IDCollection, found bool) {
store := ctx.KVStore(k.storeKey)
b := store.Get(types.GetOwnerKey(owner, denom))
if b == nil {
return types.NewIDCollection(denom, []string{}), false
}
k.cdc.MustUnmarshalBinaryLengthPrefixed(b, &idCollection)
return idCollection, true
}
// SetOwnerByDenom sets a collection of NFT IDs owned by an address
func (k Keeper) SetOwnerByDenom(ctx sdk.Context, owner sdk.AccAddress, denom string, ids []string) {
store := ctx.KVStore(k.storeKey)
key := types.GetOwnerKey(owner, denom)
var idCollection types.IDCollection
idCollection.Denom = denom
idCollection.IDs = ids
store.Set(key, k.cdc.MustMarshalBinaryLengthPrefixed(idCollection))
}
// SetOwner sets an entire Owner
func (k Keeper) SetOwner(ctx sdk.Context, owner types.Owner) {
for _, idCollection := range owner.IDCollections {
k.SetOwnerByDenom(ctx, owner.Address, idCollection.Denom, idCollection.IDs)
}
}
// SetOwners sets all Owners
func (k Keeper) SetOwners(ctx sdk.Context, owners []types.Owner) {
for _, owner := range owners {
k.SetOwner(ctx, owner)
}
}
// IterateIDCollections iterates over the IDCollections by Owner and performs a function
func (k Keeper) IterateIDCollections(ctx sdk.Context, prefix []byte,
handler func(owner sdk.AccAddress, idCollection types.IDCollection) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, prefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var idCollection types.IDCollection
k.cdc.MustUnmarshalBinaryLengthPrefixed(iterator.Value(), &idCollection)
owner, _ := types.SplitOwnerKey(iterator.Key())
if handler(owner, idCollection) {
break
}
}
}
// IterateOwners iterates over all Owners and performs a function
func (k Keeper) IterateOwners(ctx sdk.Context, handler func(owner types.Owner) (stop bool)) {
store := ctx.KVStore(k.storeKey)
iterator := sdk.KVStorePrefixIterator(store, types.OwnersKeyPrefix)
defer iterator.Close()
for ; iterator.Valid(); iterator.Next() {
var owner types.Owner
address, _ := types.SplitOwnerKey(iterator.Key())
owner = k.GetOwner(ctx, address)
if handler(owner) {
break
}
}
}
// SwapOwners swaps the owners of a NFT ID
func (k Keeper) SwapOwners(ctx sdk.Context, denom string, id string, oldAddress sdk.AccAddress, newAddress sdk.AccAddress) (err error) {
oldOwnerIDCollection, found := k.GetOwnerByDenom(ctx, oldAddress, denom)
if !found {
return sdkerrors.Wrapf(types.ErrUnknownCollection, "id collection %s doesn't exist for owner %s", denom, oldAddress)
}
oldOwnerIDCollection, err = oldOwnerIDCollection.DeleteID(id)
if err != nil {
return err
}
k.SetOwnerByDenom(ctx, oldAddress, denom, oldOwnerIDCollection.IDs)
newOwnerIDCollection, found := k.GetOwnerByDenom(ctx, newAddress, denom)
if !found {
newOwnerIDCollection = types.NewIDCollection(denom, []string{})
}
newOwnerIDCollection = newOwnerIDCollection.AddID(id)
k.SetOwnerByDenom(ctx, newAddress, denom, newOwnerIDCollection.IDs)
return nil
}