1- import { fetchAnalytics } from "data/analytics/fetch-analytics" ;
1+ import "server-only" ;
2+
23import type {
34 AnalyticsQueryParams ,
4- AnalyticsQueryParamsV2 ,
5+ EcosystemWalletStats ,
56 InAppWalletStats ,
67 RpcMethodStats ,
78 TransactionStats ,
89 UserOpStats ,
910 WalletStats ,
1011 WalletUserStats ,
1112} from "types/analytics" ;
13+ import { getAuthToken } from "../../app/api/lib/getAuthToken" ;
1214import { getChains } from "./chain" ;
1315
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 ( ) ;
1821
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" ) ;
2224 }
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" ) ;
2529 }
2630
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+ ) ;
3045 }
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 ) {
3270 searchParams . append ( "projectId" , params . projectId ) ;
3371 }
3472
@@ -46,7 +84,7 @@ function buildSearchParams(
4684}
4785
4886export async function getWalletConnections (
49- params : AnalyticsQueryParamsV2 ,
87+ params : AnalyticsQueryParams ,
5088) : Promise < WalletStats [ ] > {
5189 const searchParams = buildSearchParams ( params ) ;
5290 const res = await fetchAnalytics (
@@ -70,7 +108,7 @@ export async function getWalletConnections(
70108}
71109
72110export async function getInAppWalletUsage (
73- params : AnalyticsQueryParamsV2 ,
111+ params : AnalyticsQueryParams ,
74112) : Promise < InAppWalletStats [ ] > {
75113 const searchParams = buildSearchParams ( params ) ;
76114 const res = await fetchAnalytics (
@@ -94,7 +132,7 @@ export async function getInAppWalletUsage(
94132}
95133
96134export async function getUserOpUsage (
97- params : AnalyticsQueryParamsV2 ,
135+ params : AnalyticsQueryParams ,
98136) : Promise < UserOpStats [ ] > {
99137 const searchParams = buildSearchParams ( params ) ;
100138 const res = await fetchAnalytics (
@@ -118,7 +156,7 @@ export async function getUserOpUsage(
118156}
119157
120158export async function getAggregateUserOpUsage (
121- params : Omit < AnalyticsQueryParamsV2 , "period" > ,
159+ params : Omit < AnalyticsQueryParams , "period" > ,
122160) : Promise < UserOpStats > {
123161 const [ userOpStats , chains ] = await Promise . all ( [
124162 getUserOpUsage ( { ...params , period : "all" } ) ,
@@ -152,7 +190,7 @@ export async function getAggregateUserOpUsage(
152190}
153191
154192export async function getClientTransactions (
155- params : AnalyticsQueryParamsV2 ,
193+ params : AnalyticsQueryParams ,
156194) : Promise < TransactionStats [ ] > {
157195 const searchParams = buildSearchParams ( params ) ;
158196 const res = await fetchAnalytics (
@@ -180,7 +218,7 @@ export async function getRpcMethodUsage(
180218) : Promise < RpcMethodStats [ ] > {
181219 const searchParams = buildSearchParams ( params ) ;
182220 const res = await fetchAnalytics (
183- `v1 /rpc/evm-methods?${ searchParams . toString ( ) } ` ,
221+ `v2 /rpc/evm-methods?${ searchParams . toString ( ) } ` ,
184222 {
185223 method : "GET" ,
186224 headers : { "Content-Type" : "application/json" } ,
@@ -201,7 +239,7 @@ export async function getWalletUsers(
201239) : Promise < WalletUserStats [ ] > {
202240 const searchParams = buildSearchParams ( params ) ;
203241 const res = await fetchAnalytics (
204- `v1/wallets /users?${ searchParams . toString ( ) } ` ,
242+ `v2/wallet-connects /users?${ searchParams . toString ( ) } ` ,
205243 {
206244 method : "GET" ,
207245 headers : { "Content-Type" : "application/json" } ,
@@ -220,23 +258,107 @@ export async function getWalletUsers(
220258 return json . data as WalletUserStats [ ] ;
221259}
222260
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+ } ;
271+
223272export async function isProjectActive (
224273 params : AnalyticsQueryParams ,
225- ) : Promise < boolean > {
274+ ) : Promise < ActiveStatus > {
226275 const searchParams = buildSearchParams ( params ) ;
227- const res = await fetchAnalytics ( `v1/active?${ searchParams . toString ( ) } ` , {
228- method : "GET" ,
229- headers : { "Content-Type" : "application/json" } ,
230- } ) ;
276+ const res = await fetchAnalytics (
277+ `v2/active-usage?${ searchParams . toString ( ) } ` ,
278+ {
279+ method : "GET" ,
280+ headers : { "Content-Type" : "application/json" } ,
281+ } ,
282+ ) ;
231283
232284 if ( res ?. status !== 200 ) {
233285 const reason = await res ?. text ( ) ;
234286 console . error (
235287 `Failed to fetch project active status: ${ res ?. status } - ${ res . statusText } - ${ reason } ` ,
236288 ) ;
237- return false ;
289+ return {
290+ bundler : false ,
291+ storage : false ,
292+ rpc : false ,
293+ nebula : false ,
294+ sdk : false ,
295+ insight : false ,
296+ pay : false ,
297+ inAppWallet : false ,
298+ ecosystemWallet : false ,
299+ } as ActiveStatus ;
238300 }
239301
240302 const json = await res . json ( ) ;
241- return json . data . isActive as boolean ;
303+ return json . data as ActiveStatus ;
304+ }
305+
306+ export async function getEcosystemWalletUsage ( args : {
307+ teamId : string ;
308+ ecosystemSlug : string ;
309+ ecosystemPartnerId ?: string ;
310+ projectId ?: string ;
311+ from ?: Date ;
312+ to ?: Date ;
313+ period ?: "day" | "week" | "month" | "year" | "all" ;
314+ } ) {
315+ const {
316+ ecosystemSlug,
317+ ecosystemPartnerId,
318+ teamId,
319+ projectId,
320+ from,
321+ to,
322+ period,
323+ } = args ;
324+
325+ const searchParams = new URLSearchParams ( ) ;
326+ // required params
327+ searchParams . append ( "ecosystemSlug" , ecosystemSlug ) ;
328+ searchParams . append ( "teamId" , teamId ) ;
329+
330+ // optional params
331+ if ( ecosystemPartnerId ) {
332+ searchParams . append ( "ecosystemPartnerId" , ecosystemPartnerId ) ;
333+ }
334+ if ( projectId ) {
335+ searchParams . append ( "projectId" , projectId ) ;
336+ }
337+ if ( from ) {
338+ searchParams . append ( "from" , from . toISOString ( ) ) ;
339+ }
340+ if ( to ) {
341+ searchParams . append ( "to" , to . toISOString ( ) ) ;
342+ }
343+ if ( period ) {
344+ searchParams . append ( "period" , period ) ;
345+ }
346+ const res = await fetchAnalytics (
347+ `v2/wallets/connects/${ ecosystemSlug } ?${ searchParams . toString ( ) } ` ,
348+ {
349+ method : "GET" ,
350+ headers : {
351+ "Content-Type" : "application/json" ,
352+ } ,
353+ } ,
354+ ) ;
355+
356+ if ( res ?. status !== 200 ) {
357+ console . error ( "Failed to fetch ecosystem wallet stats" ) ;
358+ return null ;
359+ }
360+
361+ const json = await res . json ( ) ;
362+
363+ return json . data as EcosystemWalletStats [ ] ;
242364}
0 commit comments