user_inventory.gno
2.99 Kb ยท 140 lines
1package block
2
3import (
4 "strconv"
5
6 "gno.land/p/demo/tokens/grc1155"
7 "gno.land/p/nt/avl"
8)
9
10var (
11 userTokenIndex = avl.NewTree() // address -> map[tid]bool
12)
13
14// addUserToken adds a token ID to user's token list
15func addUserToken(user address, tid grc1155.TokenID) {
16 userStr := user.String()
17
18 // Get or create user's token map
19 var tokensMap map[string]bool
20 tokens, found := userTokenIndex.Get(userStr)
21 if found {
22 tokensMap = tokens.(map[string]bool)
23 } else {
24 tokensMap = make(map[string]bool)
25 userTokenIndex.Set(userStr, tokensMap)
26 }
27
28 tidStr := string(tid)
29 tokensMap[tidStr] = true
30}
31
32// addUserTokenBatch adds multiple token IDs to user's token list
33func addUserTokenBatch(user address, tids []grc1155.TokenID) {
34 userStr := user.String()
35
36 // Get or create user's token map
37 var tokensMap map[string]bool
38 tokens, found := userTokenIndex.Get(userStr)
39 if found {
40 tokensMap = tokens.(map[string]bool)
41 } else {
42 tokensMap = make(map[string]bool)
43 userTokenIndex.Set(userStr, tokensMap)
44 }
45
46 for _, tid := range tids {
47 tidStr := string(tid)
48 tokensMap[tidStr] = true
49 }
50}
51
52// removeUserToken removes a token ID from user's token list if balance is 0
53func removeUserToken(user address, tid grc1155.TokenID) {
54 balance := BalanceOf(user, tid)
55 if balance != 0 {
56 return
57 }
58
59 userStr := user.String()
60 tokens, found := userTokenIndex.Get(userStr)
61 if !found {
62 return
63 }
64
65 tokensMap := tokens.(map[string]bool)
66 tidStr := string(tid)
67 delete(tokensMap, tidStr)
68
69 // Remove user entry if no tokens left
70 if len(tokensMap) == 0 {
71 userTokenIndex.Remove(userStr)
72 }
73}
74
75// removeUserTokenBatch removes multiple token IDs from user's token list
76func removeUserTokenBatch(user address, tids []grc1155.TokenID) {
77 userStr := user.String()
78 tokens, found := userTokenIndex.Get(userStr)
79 if !found {
80 return
81 }
82
83 tokensMap := tokens.(map[string]bool)
84 for _, tid := range tids {
85 balance := BalanceOf(user, tid)
86 if balance != 0 {
87 continue
88 }
89 tidStr := string(tid)
90 delete(tokensMap, tidStr)
91 }
92
93 // Remove user entry if no tokens left
94 if len(tokensMap) == 0 {
95 userTokenIndex.Remove(userStr)
96 }
97}
98
99// getUserTokens returns all token IDs owned by user
100func getUserTokens(user address) []string {
101 userStr := user.String()
102 tokens, found := userTokenIndex.Get(userStr)
103 if !found {
104 return []string{}
105 }
106
107 tokensMap := tokens.(map[string]bool)
108 result := make([]string, 0, len(tokensMap))
109
110 for tid := range tokensMap {
111 result = append(result, tid)
112 }
113
114 return result
115}
116
117// GetInventory returns all block tokens owned by user with their balances
118func GetInventory(user address) []map[string]string {
119 result := []map[string]string{}
120
121 // Get all token IDs owned by user
122 tids := getUserTokens(user)
123
124 for _, tid := range tids {
125 balance, err := token.BalanceOf(user, grc1155.TokenID(tid))
126 if err != nil {
127 continue
128 }
129
130 // Only include tokens with non-zero balance
131 if balance > 0 {
132 result = append(result, map[string]string{
133 "id": tid,
134 "balance": strconv.FormatInt(balance, 10),
135 })
136 }
137 }
138
139 return result
140}