feat: GET /tokens endpoint with pagination#239
feat: GET /tokens endpoint with pagination#239sadiq1971 wants to merge 3 commits intofeat/user-info-v2from
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a new /tokens endpoint to provide a paginated and sorted list of supported tokens. The implementation includes the HTTP routing, service-level logic for pagination and sorting, and comprehensive unit tests. Feedback highlights a security concern regarding the default disabling of the whitelist check in the Docker configuration and a potential integer overflow in the pagination calculation that could cause a service panic.
I am having trouble creating individual review comments. Click here to see my feedback.
pkg/config/defaults/config.api-server.docker.yaml (96)
Disabling skip_whitelist_check by default in the Docker configuration is a security regression. This setting allows any user to register with the relayer without being on a whitelist. If this change was intended for local development or testing, it should be managed via environment variables (e.g., ${SKIP_WHITELIST_CHECK}) or a separate development-specific configuration file to ensure production-like environments remain secure by default.
pkg/token/service.go (68-72)
The calculation of the start index can overflow if a very large page number is provided (e.g., math.MaxInt). Since limit is at least 1, an overflow could result in a negative start value, causing a runtime panic when slicing addrs. Adding a check to ensure page is within a reasonable range relative to the total number of tokens prevents this potential Denial of Service (DoS) vulnerability.
total := len(addrs)
if total == 0 || page > total {
return &TokensPage{Items: []TokenItem{}, Total: total, Page: page, Limit: limit}, nil
}
start := (page - 1) * limit
if start >= total {
return &TokensPage{Items: []TokenItem{}, Total: total, Page: page, Limit: limit}, nil
}
Codecov Report❌ Patch coverage is
❌ Your patch status has failed because the patch coverage (49.12%) is below the target coverage (50.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## feat/user-info-v2 #239 +/- ##
=====================================================
+ Coverage 31.51% 33.15% +1.63%
=====================================================
Files 124 124
Lines 10448 8671 -1777
=====================================================
- Hits 3293 2875 -418
+ Misses 6906 5547 -1359
Partials 249 249
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
| } | ||
|
|
||
| func (h *HTTP) listTokens(w http.ResponseWriter, r *http.Request) error { | ||
| page, limit, err := parsePagination(r) |
There was a problem hiding this comment.
I think we should use cursor approach here instead of pages for pagination. The response we can return could be.
{
"items": [...],
"next_cursor": "...",
"has_more": true
}
Let me know what you think.
Why this is needed
The dApp needs a supported token list to function correctly at startup and throughout the session:
decimalsfield. Fetching this from the API keeps it in sync with the server config and avoids drift when tokens are added or removed./tokenson connect and renders whatever the server exposes.What changed
pkg/token/types.go— addedTokenItemandTokensPageresponse types.pkg/token/service.go— addedGetSupportedTokens(ctx, page, limit)to*Service; tokens sorted by address hex for stable pagination across requests.pkg/token/http.go— new file;ListServiceinterface,HTTPstruct,RegisterRoutes,listTokenshandler withparsePagination(?page,?limit; defaults 1/50; max limit 200; 400 on invalid input).pkg/token/http_test.go— new file; 6 tests covering default pagination, explicit params, invalid page/limit values, service error, and empty list.pkg/token/mocks/mock_list_service.go— generated mock forListService.pkg/app/api/server.go— replaced 19-line inline closure withtoken.RegisterRoutes(r, tokenService, logger).Endpoint
Response:
{ "items": [ { "address": "0x...", "name": "Demo Token", "symbol": "DEMO", "decimals": 18 } ], "total": 2, "page": 1, "limit": 50 }Test plan
go test ./pkg/token/...— all tests green.GET /tokensreturns 200 with token list.GET /tokens?page=2&limit=1pages correctly.GET /tokens?limit=999returns 400.