Skip to content

Commit ad52f33

Browse files
feat(frontend): nft token inventory (#1358)
1 parent f329f20 commit ad52f33

File tree

65 files changed

+1302
-474
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+1302
-474
lines changed

apps/api/src/routes/v3/fts/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ const routes = (app: Router) => {
5151
* description: Sort field
5252
* schema:
5353
* type: string
54-
* enum: [change_24h, holders, market_cap, name, onchain_market_cap, price, volume_24h]
54+
* enum: [market_cap, name, onchain_market_cap, price, volume_24h]
5555
* default: onchain_market_cap
5656
* - in: query
5757
* name: order

apps/api/src/routes/v3/nfts/index.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { bearerAuth } from '#middlewares/passport';
66
import rateLimiter from '#middlewares/rateLimiter';
77
import { validate } from '#middlewares/validate';
88
import contract from '#routes/v3/nfts/contract';
9+
import token from '#routes/v3/nfts/token';
910
import service from '#services/v3/nfts/index';
1011

1112
const route = Router();
@@ -14,6 +15,7 @@ const routes = (app: Router) => {
1415
app.use('/nfts', bearerAuth, rateLimiter, route);
1516

1617
contract(app);
18+
token(app);
1719

1820
/**
1921
* @openapi
@@ -51,7 +53,7 @@ const routes = (app: Router) => {
5153
* description: Sort field
5254
* schema:
5355
* type: string
54-
* enum: [holders, name, tokens, transfers_24h]
56+
* enum: [name, tokens, transfers_24h]
5557
* default: transfers_24h
5658
* - in: query
5759
* name: order
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
import { Router } from 'express';
2+
3+
import request from 'nb-schemas/dist/nfts/tokens/request.js';
4+
5+
import { bearerAuth } from '#middlewares/passport';
6+
import rateLimiter from '#middlewares/rateLimiter';
7+
import { validate } from '#middlewares/validate';
8+
import service from '#services/v3/nfts/token';
9+
10+
const route = Router();
11+
12+
const routes = (app: Router) => {
13+
app.use('/nfts', bearerAuth, rateLimiter, route);
14+
15+
/**
16+
* @openapi
17+
* /v3/nfts/{contract}/tokens:
18+
* get:
19+
* summary: Get nft tokens
20+
* tags:
21+
* - V3 / NFTs
22+
* parameters:
23+
* - in: path
24+
* name: contract
25+
* required: true
26+
* description: Contract ID
27+
* schema:
28+
* type: string
29+
* - in: query
30+
* name: next
31+
* description: Next page cursor. Pass the next_page value returned from the previous response to retrieve the next page of results
32+
* schema:
33+
* type: string
34+
* - in: query
35+
* name: prev
36+
* description: Previous page cursor. Pass the prev_page value returned from the previous response to retrieve the previous page of results
37+
* schema:
38+
* type: string
39+
* - in: query
40+
* name: limit
41+
* description: The number of items to return. Each increment of 25 will count towards rate limit. For example, limit 50 will use 2 credits
42+
* schema:
43+
* type: integer
44+
* minimum: 1
45+
* maximum: 100
46+
* default: 25
47+
* responses:
48+
* 200:
49+
* description: Success response
50+
*/
51+
route.get('/:contract/tokens', validate(request.list), service.list);
52+
53+
/**
54+
* @openapi
55+
* /v3/nfts/{contract}/tokens/count:
56+
* get:
57+
* summary: Get nft tokens count
58+
* tags:
59+
* - V3 / NFTs
60+
* parameters:
61+
* - in: path
62+
* name: contract
63+
* required: true
64+
* description: Contract ID
65+
* schema:
66+
* type: string
67+
* responses:
68+
* 200:
69+
* description: Success response
70+
*/
71+
route.get(
72+
'/:contract/tokens/count',
73+
validate(request.tokenCount),
74+
service.tokenCount,
75+
);
76+
77+
/**
78+
* @openapi
79+
* /v3/nfts/{contract}/tokens/{token}:
80+
* get:
81+
* summary: Get nft token info
82+
* tags:
83+
* - V3 / NFTs
84+
* parameters:
85+
* - in: path
86+
* name: contract
87+
* required: true
88+
* description: Contract ID
89+
* schema:
90+
* type: string
91+
* - in: path
92+
* name: token
93+
* required: true
94+
* description: Token ID
95+
* schema:
96+
* type: string
97+
* responses:
98+
* 200:
99+
* description: Success response
100+
*/
101+
route.get('/:contract/tokens/:token', validate(request.token), service.token);
102+
103+
/**
104+
* @openapi
105+
* /v3/nfts/{contract}/tokens/{token}/txns:
106+
* get:
107+
* summary: Get nft token transfers
108+
* tags:
109+
* - V3 / NFTs
110+
* parameters:
111+
* - in: path
112+
* name: contract
113+
* required: true
114+
* description: Contract ID
115+
* schema:
116+
* type: string
117+
* - in: path
118+
* name: token
119+
* required: true
120+
* description: Token ID
121+
* schema:
122+
* type: string
123+
* - in: query
124+
* name: before_ts
125+
* description: Timestamp in nanoseconds. Return results before this timestamp (exclusive)
126+
* schema:
127+
* type: string
128+
* minLength: 19
129+
* maxLength: 19
130+
* - in: query
131+
* name: next
132+
* description: Next page cursor. Pass the next_page value returned from the previous response to retrieve the next page of results
133+
* schema:
134+
* type: string
135+
* - in: query
136+
* name: prev
137+
* description: Previous page cursor. Pass the prev_page value returned from the previous response to retrieve the previous page of results
138+
* schema:
139+
* type: string
140+
* - in: query
141+
* name: limit
142+
* description: The number of items to return. Each increment of 25 will count towards rate limit. For example, limit 50 will use 2 credits
143+
* schema:
144+
* type: integer
145+
* minimum: 1
146+
* maximum: 100
147+
* default: 25
148+
* responses:
149+
* 200:
150+
* description: Success response
151+
*/
152+
route.get(
153+
'/:contract/tokens/:token/txns',
154+
validate(request.txns),
155+
service.txns,
156+
);
157+
158+
/**
159+
* @openapi
160+
* /v3/nfts/{contract}/tokens/{token}/txns/count:
161+
* get:
162+
* summary: Get nft token transfers count
163+
* tags:
164+
* - V3 / NFTs
165+
* parameters:
166+
* - in: path
167+
* name: contract
168+
* required: true
169+
* description: Contract ID
170+
* schema:
171+
* type: string
172+
* - in: path
173+
* name: token
174+
* required: true
175+
* description: Token ID
176+
* schema:
177+
* type: string
178+
* - in: query
179+
* name: before_ts
180+
* description: Timestamp in nanoseconds. Return results before this timestamp (exclusive)
181+
* schema:
182+
* type: string
183+
* minLength: 19
184+
* maxLength: 19
185+
* responses:
186+
* 200:
187+
* description: Success response
188+
*/
189+
route.get(
190+
'/:contract/tokens/:token/txns/count',
191+
validate(request.txnCount),
192+
service.txnCount,
193+
);
194+
};
195+
196+
export default routes;

apps/api/src/services/v3/fts/contract.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,9 +166,11 @@ const holders = responseHandler(
166166
? cursors.decode(request.contractHoldersCursor, req.validator.prev)
167167
: null;
168168
const direction = prev ? 'asc' : 'desc';
169+
const accountDirection = prev ? 'desc' : 'asc';
169170
const cursor = prev || next;
170171

171172
const data = await dbEvents.manyOrNone<FTContractHolders>(sql.holders, {
173+
accountDirection,
172174
contract,
173175
cursor: {
174176
account: cursor?.account,

apps/api/src/services/v3/nfts/contract.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,17 @@ const holders = responseHandler(
163163
? cursors.decode(request.contractHoldersCursor, req.validator.prev)
164164
: null;
165165
const direction = prev ? 'asc' : 'desc';
166+
const accountDirection = prev ? 'desc' : 'asc';
166167
const cursor = prev || next;
167168

168169
const data = await dbEvents.manyOrNone<NFTContractHolders>(sql.holders, {
170+
accountDirection,
169171
contract,
170172
cursor: {
171173
account: cursor?.account,
172174
quantity: cursor?.quantity,
173175
},
176+
direction,
174177
// Fetch one extra to check if there is a next page
175178
limit: limit + 1,
176179
});

0 commit comments

Comments
 (0)