Skip to content

Commit 9f885c5

Browse files
committed
feat: support multiple token types in query
1 parent f3e46ac commit 9f885c5

File tree

3 files changed

+47
-17
lines changed

3 files changed

+47
-17
lines changed

internal/handlers/token_handlers.go

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,15 +48,20 @@ func GetTokenBalancesByType(c *gin.Context) {
4848
api.BadRequestErrorHandler(c, err)
4949
return
5050
}
51-
tokenType := c.Param("type")
52-
if tokenType == "" {
53-
tokenType = c.Query("token_type")
51+
52+
tokenTypesStr := c.Param("type")
53+
if tokenTypesStr == "" {
54+
tokenTypesStr = c.Query("token_types")
5455
}
5556

56-
if tokenType != "" && tokenType != "erc20" && tokenType != "erc1155" && tokenType != "erc721" {
57-
api.BadRequestErrorHandler(c, fmt.Errorf("invalid token type '%s'", tokenType))
57+
tokenTypesStr = strings.ToLower(tokenTypesStr)
58+
tokenTypes, err := parseTokenType(tokenTypesStr)
59+
60+
if err != nil {
61+
api.BadRequestErrorHandler(c, err)
5862
return
5963
}
64+
6065
owner := strings.ToLower(c.Param("owner"))
6166
if !strings.HasPrefix(owner, "0x") {
6267
api.BadRequestErrorHandler(c, fmt.Errorf("invalid owner address '%s'", owner))
@@ -71,7 +76,7 @@ func GetTokenBalancesByType(c *gin.Context) {
7176
tokenIds := []*big.Int{}
7277
tokenIdsStr := strings.TrimSpace(c.Query("token_ids"))
7378
if tokenIdsStr != "" {
74-
tokenIds, err = parseTokenIds(c.Query("token_ids"))
79+
tokenIds, err = parseTokenIds(tokenIdsStr)
7580
if err != nil {
7681
api.BadRequestErrorHandler(c, fmt.Errorf("invalid token ids '%s'", tokenIdsStr))
7782
return
@@ -82,15 +87,15 @@ func GetTokenBalancesByType(c *gin.Context) {
8287

8388
columns := []string{"address", "sum(balance) as balance"}
8489
groupBy := []string{"address"}
85-
if tokenType != "erc20" {
90+
if !strings.Contains(tokenTypesStr, "erc20") {
8691
columns = []string{"address", "token_id", "sum(balance) as balance"}
8792
groupBy = []string{"address", "token_id"}
8893
}
8994

9095
qf := storage.BalancesQueryFilter{
9196
ChainId: chainId,
9297
Owner: owner,
93-
TokenType: tokenType,
98+
TokenTypes: tokenTypes,
9499
TokenAddress: tokenAddress,
95100
ZeroBalance: hideZeroBalances,
96101
TokenIds: tokenIds,
@@ -148,8 +153,24 @@ func serializeBalance(balance common.TokenBalance) BalanceModel {
148153
}
149154
}
150155

156+
func parseTokenType(input string) ([]string, error) {
157+
tokenTypes := []string{input}
158+
if strings.Contains(input, ",") {
159+
tokenTypes = strings.Split(input, ",")
160+
}
161+
for _, tokenType := range tokenTypes {
162+
if tokenType != "erc721" && tokenType != "erc1155" && tokenType != "erc20" {
163+
return []string{}, fmt.Errorf("invalid token type: %s", tokenType)
164+
}
165+
}
166+
return tokenTypes, nil
167+
}
168+
151169
func parseTokenIds(input string) ([]*big.Int, error) {
152-
tokenIdsStr := strings.Split(input, ",")
170+
tokenIdsStr := []string{input}
171+
if strings.Contains(input, ",") {
172+
tokenIdsStr = strings.Split(input, ",")
173+
}
153174
tokenIdsBn := make([]*big.Int, len(tokenIdsStr))
154175

155176
for i, strNum := range tokenIdsStr {
@@ -197,16 +218,18 @@ func GetTokenHoldersByType(c *gin.Context) {
197218
return
198219
}
199220

200-
tokenType := c.Query("token_type")
201-
if tokenType != "" && tokenType != "erc20" && tokenType != "erc1155" && tokenType != "erc721" {
202-
api.BadRequestErrorHandler(c, fmt.Errorf("invalid token type '%s'", tokenType))
221+
tokenTypesStr := strings.ToLower(c.Query("token_types"))
222+
tokenTypes, err := parseTokenType(tokenTypesStr)
223+
if err != nil {
224+
api.BadRequestErrorHandler(c, err)
203225
return
204226
}
205227
hideZeroBalances := c.Query("hide_zero_balances") != "false"
206228

207229
columns := []string{"owner", "sum(balance) as balance"}
208230
groupBy := []string{"owner"}
209-
if tokenType != "erc20" {
231+
232+
if !strings.Contains(tokenTypesStr, "erc20") {
210233
columns = []string{"owner", "token_id", "sum(balance) as balance"}
211234
groupBy = []string{"owner", "token_id"}
212235
}
@@ -223,7 +246,7 @@ func GetTokenHoldersByType(c *gin.Context) {
223246

224247
qf := storage.BalancesQueryFilter{
225248
ChainId: chainId,
226-
TokenType: tokenType,
249+
TokenTypes: tokenTypes,
227250
TokenAddress: address,
228251
ZeroBalance: hideZeroBalances,
229252
TokenIds: tokenIds,

internal/storage/clickhouse.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1399,9 +1399,16 @@ func (c *ClickHouseConnector) GetTokenBalances(qf BalancesQueryFilter, fields ..
13991399
}
14001400
query := fmt.Sprintf("SELECT %s FROM %s.token_balances WHERE chain_id = ?", columns, c.cfg.Database)
14011401

1402-
if qf.TokenType != "" {
1403-
query += fmt.Sprintf(" AND token_type = '%s'", qf.TokenType)
1402+
if len(qf.TokenTypes) > 0 {
1403+
tokenTypesStr := ""
1404+
tokenTypesLen := len(qf.TokenTypes)
1405+
for i := 0; i < tokenTypesLen-1; i++ {
1406+
tokenTypesStr += fmt.Sprintf("'%s',", qf.TokenTypes[i])
1407+
}
1408+
tokenTypesStr += fmt.Sprintf("'%s'", qf.TokenTypes[tokenTypesLen-1])
1409+
query += fmt.Sprintf(" AND token_type in (%s)", tokenTypesStr)
14041410
}
1411+
14051412
if qf.Owner != "" {
14061413
query += fmt.Sprintf(" AND owner = '%s'", qf.Owner)
14071414
}

internal/storage/connector.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ type QueryFilter struct {
2727

2828
type BalancesQueryFilter struct {
2929
ChainId *big.Int
30-
TokenType string
30+
TokenTypes []string
3131
TokenAddress string
3232
Owner string
3333
TokenIds []*big.Int

0 commit comments

Comments
 (0)