1
- import { fetchAnalytics } from "data/analytics/fetch-analytics" ;
1
+ import "server-only" ;
2
+
2
3
import type {
3
4
AnalyticsQueryParams ,
4
- AnalyticsQueryParamsV2 ,
5
+ EcosystemWalletStats ,
5
6
InAppWalletStats ,
6
7
RpcMethodStats ,
7
8
TransactionStats ,
8
9
UserOpStats ,
9
10
WalletStats ,
10
11
WalletUserStats ,
11
12
} from "types/analytics" ;
13
+ import { getAuthToken } from "../../app/api/lib/getAuthToken" ;
12
14
import { getChains } from "./chain" ;
13
15
14
- function buildSearchParams (
15
- params : AnalyticsQueryParams | AnalyticsQueryParamsV2 ,
16
- ) : URLSearchParams {
17
- const searchParams = new URLSearchParams ( ) ;
16
+ async function fetchAnalytics (
17
+ input : string | URL ,
18
+ init ?: RequestInit ,
19
+ ) : Promise < Response > {
20
+ const token = await getAuthToken ( ) ;
18
21
19
- // v1 params
20
- if ( "clientId" in params && params . clientId ) {
21
- searchParams . append ( "clientId" , params . clientId ) ;
22
+ if ( ! token ) {
23
+ throw new Error ( "You are not authorized to perform this action" ) ;
22
24
}
23
- if ( "accountId" in params && params . accountId ) {
24
- searchParams . append ( "accountId" , params . accountId ) ;
25
+
26
+ const [ pathname , searchParams ] = input . toString ( ) . split ( "?" ) ;
27
+ if ( ! pathname ) {
28
+ throw new Error ( "Invalid input, no pathname provided" ) ;
25
29
}
26
30
27
- // v2 params
28
- if ( "teamId" in params && params . teamId ) {
29
- searchParams . append ( "teamId" , params . teamId ) ;
31
+ // create a new URL object for the analytics server
32
+ const ANALYTICS_SERVICE_URL = new URL (
33
+ process . env . ANALYTICS_SERVICE_URL || "https://analytics.thirdweb.com" ,
34
+ ) ;
35
+ ANALYTICS_SERVICE_URL . pathname = pathname ;
36
+ for ( const param of searchParams ?. split ( "&" ) || [ ] ) {
37
+ const [ key , value ] = param . split ( "=" ) ;
38
+ if ( ! key || ! value ) {
39
+ throw new Error ( "Invalid input, no key or value provided" ) ;
40
+ }
41
+ ANALYTICS_SERVICE_URL . searchParams . append (
42
+ decodeURIComponent ( key ) ,
43
+ decodeURIComponent ( value ) ,
44
+ ) ;
30
45
}
31
- if ( "projectId" in params && params . projectId ) {
46
+ // client id DEBUG OVERRIDE
47
+ // ANALYTICS_SERVICE_URL.searchParams.delete("clientId");
48
+ // ANALYTICS_SERVICE_URL.searchParams.delete("accountId");
49
+ // ANALYTICS_SERVICE_URL.searchParams.append(
50
+ // "clientId",
51
+ // "...",
52
+ // );
53
+
54
+ return fetch ( ANALYTICS_SERVICE_URL , {
55
+ ...init ,
56
+ headers : {
57
+ "content-type" : "application/json" ,
58
+ ...init ?. headers ,
59
+ authorization : `Bearer ${ token } ` ,
60
+ } ,
61
+ } ) ;
62
+ }
63
+
64
+ function buildSearchParams ( params : AnalyticsQueryParams ) : URLSearchParams {
65
+ const searchParams = new URLSearchParams ( ) ;
66
+
67
+ searchParams . append ( "teamId" , params . teamId ) ;
68
+
69
+ if ( params . projectId ) {
32
70
searchParams . append ( "projectId" , params . projectId ) ;
33
71
}
34
72
@@ -46,7 +84,7 @@ function buildSearchParams(
46
84
}
47
85
48
86
export async function getWalletConnections (
49
- params : AnalyticsQueryParamsV2 ,
87
+ params : AnalyticsQueryParams ,
50
88
) : Promise < WalletStats [ ] > {
51
89
const searchParams = buildSearchParams ( params ) ;
52
90
const res = await fetchAnalytics (
@@ -70,7 +108,7 @@ export async function getWalletConnections(
70
108
}
71
109
72
110
export async function getInAppWalletUsage (
73
- params : AnalyticsQueryParamsV2 ,
111
+ params : AnalyticsQueryParams ,
74
112
) : Promise < InAppWalletStats [ ] > {
75
113
const searchParams = buildSearchParams ( params ) ;
76
114
const res = await fetchAnalytics (
@@ -94,7 +132,7 @@ export async function getInAppWalletUsage(
94
132
}
95
133
96
134
export async function getUserOpUsage (
97
- params : AnalyticsQueryParamsV2 ,
135
+ params : AnalyticsQueryParams ,
98
136
) : Promise < UserOpStats [ ] > {
99
137
const searchParams = buildSearchParams ( params ) ;
100
138
const res = await fetchAnalytics (
@@ -118,7 +156,7 @@ export async function getUserOpUsage(
118
156
}
119
157
120
158
export async function getAggregateUserOpUsage (
121
- params : Omit < AnalyticsQueryParamsV2 , "period" > ,
159
+ params : Omit < AnalyticsQueryParams , "period" > ,
122
160
) : Promise < UserOpStats > {
123
161
const [ userOpStats , chains ] = await Promise . all ( [
124
162
getUserOpUsage ( { ...params , period : "all" } ) ,
@@ -152,7 +190,7 @@ export async function getAggregateUserOpUsage(
152
190
}
153
191
154
192
export async function getClientTransactions (
155
- params : AnalyticsQueryParamsV2 ,
193
+ params : AnalyticsQueryParams ,
156
194
) : Promise < TransactionStats [ ] > {
157
195
const searchParams = buildSearchParams ( params ) ;
158
196
const res = await fetchAnalytics (
@@ -180,7 +218,7 @@ export async function getRpcMethodUsage(
180
218
) : Promise < RpcMethodStats [ ] > {
181
219
const searchParams = buildSearchParams ( params ) ;
182
220
const res = await fetchAnalytics (
183
- `v1 /rpc/evm-methods?${ searchParams . toString ( ) } ` ,
221
+ `v2 /rpc/evm-methods?${ searchParams . toString ( ) } ` ,
184
222
{
185
223
method : "GET" ,
186
224
headers : { "Content-Type" : "application/json" } ,
@@ -201,7 +239,7 @@ export async function getWalletUsers(
201
239
) : Promise < WalletUserStats [ ] > {
202
240
const searchParams = buildSearchParams ( params ) ;
203
241
const res = await fetchAnalytics (
204
- `v1/wallets /users?${ searchParams . toString ( ) } ` ,
242
+ `v2/wallet-connects /users?${ searchParams . toString ( ) } ` ,
205
243
{
206
244
method : "GET" ,
207
245
headers : { "Content-Type" : "application/json" } ,
@@ -220,23 +258,108 @@ export async function getWalletUsers(
220
258
return json . data as WalletUserStats [ ] ;
221
259
}
222
260
261
+ type ActiveStatus = {
262
+ bundler : boolean ;
263
+ storage : boolean ;
264
+ rpc : boolean ;
265
+ nebula : boolean ;
266
+ sdk : boolean ;
267
+ insight : boolean ;
268
+ pay : boolean ;
269
+ inAppWallet : boolean ;
270
+ ecosystemWallet : boolean ;
271
+ } ;
272
+
223
273
export async function isProjectActive (
224
274
params : AnalyticsQueryParams ,
225
- ) : Promise < boolean > {
275
+ ) : Promise < ActiveStatus > {
226
276
const searchParams = buildSearchParams ( params ) ;
227
- const res = await fetchAnalytics ( `v1/active?${ searchParams . toString ( ) } ` , {
228
- method : "GET" ,
229
- headers : { "Content-Type" : "application/json" } ,
230
- } ) ;
277
+ const res = await fetchAnalytics (
278
+ `v2/active-usage?${ searchParams . toString ( ) } ` ,
279
+ {
280
+ method : "GET" ,
281
+ headers : { "Content-Type" : "application/json" } ,
282
+ } ,
283
+ ) ;
231
284
232
285
if ( res ?. status !== 200 ) {
233
286
const reason = await res ?. text ( ) ;
234
287
console . error (
235
288
`Failed to fetch project active status: ${ res ?. status } - ${ res . statusText } - ${ reason } ` ,
236
289
) ;
237
- return false ;
290
+ return {
291
+ bundler : false ,
292
+ storage : false ,
293
+ rpc : false ,
294
+ nebula : false ,
295
+ sdk : false ,
296
+ insight : false ,
297
+ pay : false ,
298
+ inAppWallet : false ,
299
+ ecosystemWallet : false ,
300
+ } as ActiveStatus ;
238
301
}
239
302
240
303
const json = await res . json ( ) ;
241
- return json . data . isActive as boolean ;
304
+ return json . data as ActiveStatus ;
305
+ }
306
+
307
+ export async function getEcosystemWalletUsage ( args : {
308
+ teamId : string ;
309
+ ecosystemSlug : string ;
310
+ ecosystemPartnerId ?: string ;
311
+ projectId ?: string ;
312
+ from ?: Date ;
313
+ to ?: Date ;
314
+ period ?: "day" | "week" | "month" | "year" | "all" ;
315
+ } ) {
316
+ const {
317
+ ecosystemSlug,
318
+ ecosystemPartnerId,
319
+ teamId,
320
+ projectId,
321
+ from,
322
+ to,
323
+ period,
324
+ } = args ;
325
+
326
+ const searchParams = new URLSearchParams ( ) ;
327
+ // required params
328
+ searchParams . append ( "ecosystemSlug" , ecosystemSlug ) ;
329
+ searchParams . append ( "teamId" , teamId ) ;
330
+
331
+ // optional params
332
+ if ( ecosystemPartnerId ) {
333
+ searchParams . append ( "ecosystemPartnerId" , ecosystemPartnerId ) ;
334
+ }
335
+ if ( projectId ) {
336
+ searchParams . append ( "projectId" , projectId ) ;
337
+ }
338
+ if ( from ) {
339
+ searchParams . append ( "from" , from . toISOString ( ) ) ;
340
+ }
341
+ if ( to ) {
342
+ searchParams . append ( "to" , to . toISOString ( ) ) ;
343
+ }
344
+ if ( period ) {
345
+ searchParams . append ( "period" , period ) ;
346
+ }
347
+ const res = await fetchAnalytics (
348
+ `v2/wallets/connects/${ ecosystemSlug } ?${ searchParams . toString ( ) } ` ,
349
+ {
350
+ method : "GET" ,
351
+ headers : {
352
+ "Content-Type" : "application/json" ,
353
+ } ,
354
+ } ,
355
+ ) ;
356
+
357
+ if ( res ?. status !== 200 ) {
358
+ console . error ( "Failed to fetch ecosystem wallet stats" ) ;
359
+ return null ;
360
+ }
361
+
362
+ const json = await res . json ( ) ;
363
+
364
+ return json . data as EcosystemWalletStats [ ] ;
242
365
}
0 commit comments