/
holder_service.go
94 lines (78 loc) · 2.87 KB
/
holder_service.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
package service
import (
"context"
"fmt"
"sort"
"github.com/tak1827/light-nft-indexer/data"
"github.com/tak1827/light-nft-indexer/server"
)
type HolderService struct {
*BaseService
}
func NewHolderService(base *BaseService) HolderServer {
return &HolderService{
BaseService: base,
}
}
func (s *HolderService) ListHolderNftToken(ctx context.Context, req *ListHolderNftTokenRequest) (*ListHolderNftTokenResponse, error) {
if err := req.ValidateBasic(); err != nil {
return nil, fmt.Errorf("at ListHolderNftToken.ValidateBasic: %w", err)
}
db, err := server.DBFromCtx(ctx)
if err != nil {
return nil, fmt.Errorf("at server.DBFromCtx: %w", err)
}
nft := data.NFTContract{Address: req.GetContractAddress()}
if err := db.Get(nft.Key(), &nft); err != nil {
return nil, fmt.Errorf("failed to get nft contract: %w", err)
}
tokens := []*data.Token{{}}
prefix := append(data.PrefixTokenOwnerIndex, []byte(fmt.Sprintf("%s%s%s%s", data.Separator, req.GetWalletAddress(), data.Separator, req.GetContractAddress()))...)
if err := db.List(prefix, &tokens); err != nil {
return nil, fmt.Errorf("failed to get list of nft tokens: %w", err)
}
return &ListHolderNftTokenResponse{NftContract: &nft, Tokens: tokenToTokenMinis(tokens)}, nil
}
func (s *HolderService) ListHolderAllNftToken(ctx context.Context, req *ListHolderAllNftTokenRequest) (*ListHolderAllNftTokenResponse, error) {
db, err := server.DBFromCtx(ctx)
if err != nil {
return nil, fmt.Errorf("at server.DBFromCtx: %w", err)
}
tokens := []*data.Token{{}}
prefix := append(data.PrefixTokenOwnerIndex, []byte(fmt.Sprintf("%s%s", data.Separator, req.GetWalletAddress()))...)
if err := db.List(prefix, &tokens); err != nil {
return nil, fmt.Errorf("failed to get list of nft tokens: %w", err)
}
// sort by contract address
sort.Slice(tokens, func(i, j int) bool {
return tokens[i].Address < tokens[j].Address
})
contracts := []*ContractWithToken{}
for _, token := range tokens {
if len(contracts) == 0 || contracts[len(contracts)-1].NftContract.Address != token.Address {
nft := data.NFTContract{Address: token.Address}
if err := db.Get(nft.Key(), &nft); err != nil {
return nil, fmt.Errorf("failed to get nft contract: %w", err)
}
mini := tokenToTokenMini(token)
contracts = append(contracts, &ContractWithToken{NftContract: &nft, Tokens: []*TokenMini{mini}})
} else {
contracts[len(contracts)-1].Tokens = append(contracts[len(contracts)-1].Tokens, tokenToTokenMini(token))
}
}
return &ListHolderAllNftTokenResponse{NftContracts: contracts}, nil
}
func tokenToTokenMini(token *data.Token) *TokenMini {
return &TokenMini{
TokenId: token.TokenId,
Owner: token.Owner,
Meta: token.Meta,
}
}
func tokenToTokenMinis(tokens []*data.Token) []*TokenMini {
tokenMinis := make([]*TokenMini, len(tokens))
for i, token := range tokens {
tokenMinis[i] = tokenToTokenMini(token)
}
return tokenMinis
}