@@ -13,7 +13,11 @@ interface ChainOverviewMetrics {
1313 chainName : string ;
1414 chainLogoURI : string ;
1515 txCount : TimeSeriesMetric ;
16- activeAddresses : TimeSeriesMetric ;
16+ activeAddresses : {
17+ daily : TimeSeriesMetric ;
18+ weekly : TimeSeriesMetric ;
19+ monthly : TimeSeriesMetric ;
20+ } ;
1721 icmMessages : ICMMetric ;
1822 validatorCount : number | string ;
1923}
@@ -22,7 +26,11 @@ interface OverviewMetrics {
2226 chains : ChainOverviewMetrics [ ] ;
2327 aggregated : {
2428 totalTxCount : TimeSeriesMetric ;
25- totalActiveAddresses : TimeSeriesMetric ;
29+ totalActiveAddresses : {
30+ daily : TimeSeriesMetric ;
31+ weekly : TimeSeriesMetric ;
32+ monthly : TimeSeriesMetric ;
33+ } ;
2634 totalICMMessages : ICMMetric ;
2735 totalValidators : number ;
2836 activeChains : number ;
@@ -89,10 +97,7 @@ async function getTimeSeriesData(
8997}
9098
9199// separate active addresses fetching with proper time intervals
92- async function getActiveAddressesData ( chainId : string , timeRange : string ) : Promise < TimeSeriesDataPoint [ ] > {
93- const intervalMapping = STATS_CONFIG . ACTIVE_ADDRESSES_INTERVALS [ timeRange as keyof typeof STATS_CONFIG . ACTIVE_ADDRESSES_INTERVALS ] ;
94- if ( ! intervalMapping ) { return [ ] }
95-
100+ async function getActiveAddressesData ( chainId : string , timeRange : string , interval : 'day' | 'week' | 'month' ) : Promise < TimeSeriesDataPoint [ ] > {
96101 try {
97102 const { startTimestamp, endTimestamp } = getTimestampsFromTimeRange ( timeRange ) ;
98103 let allResults : any [ ] = [ ] ;
@@ -102,7 +107,7 @@ async function getActiveAddressesData(chainId: string, timeRange: string): Promi
102107 metric : 'activeAddresses' ,
103108 startTimestamp,
104109 endTimestamp,
105- timeInterval : intervalMapping ,
110+ timeInterval : interval ,
106111 pageSize : 1 ,
107112 } ;
108113
@@ -122,7 +127,7 @@ async function getActiveAddressesData(chainId: string, timeRange: string): Promi
122127 date : new Date ( result . timestamp * 1000 ) . toISOString ( ) . split ( 'T' ) [ 0 ]
123128 } ) ) ;
124129 } catch ( error ) {
125- console . warn ( `Failed to fetch active addresses data for chain ${ chainId } :` , error ) ;
130+ console . warn ( `Failed to fetch active addresses data for chain ${ chainId } with interval ${ interval } :` , error ) ;
126131 return [ ] ;
127132 }
128133}
@@ -194,9 +199,11 @@ async function fetchChainMetrics(chain: any, timeRange: string): Promise<ChainOv
194199 const config = STATS_CONFIG . TIME_RANGES [ timeRange as keyof typeof STATS_CONFIG . TIME_RANGES ] || STATS_CONFIG . TIME_RANGES [ '30d' ] ;
195200 const { pageSize, fetchAllPages } = config ;
196201
197- const [ txCountData , activeAddressesData , icmData , validatorCount ] = await Promise . all ( [
202+ const [ txCountData , dailyAddresses , weeklyAddresses , monthlyAddresses , icmData , validatorCount ] = await Promise . all ( [
198203 getTimeSeriesData ( 'txCount' , chain . chainId , timeRange , pageSize , fetchAllPages ) ,
199- getActiveAddressesData ( chain . chainId , timeRange ) ,
204+ getActiveAddressesData ( chain . chainId , timeRange , 'day' ) ,
205+ getActiveAddressesData ( chain . chainId , timeRange , 'week' ) ,
206+ getActiveAddressesData ( chain . chainId , timeRange , 'month' ) ,
200207 getICMData ( chain . chainId , timeRange ) ,
201208 getValidatorCount ( chain . subnetId ) ,
202209 ] ) ;
@@ -206,7 +213,11 @@ async function fetchChainMetrics(chain: any, timeRange: string): Promise<ChainOv
206213 chainName : chain . chainName ,
207214 chainLogoURI : chain . logoUri ,
208215 txCount : createTimeSeriesMetricWithPeriodSum ( txCountData ) , // Period sum for overview
209- activeAddresses : createTimeSeriesMetric ( activeAddressesData ) ,
216+ activeAddresses : {
217+ daily : createTimeSeriesMetric ( dailyAddresses ) ,
218+ weekly : createTimeSeriesMetric ( weeklyAddresses ) ,
219+ monthly : createTimeSeriesMetric ( monthlyAddresses ) ,
220+ } ,
210221 icmMessages : createICMMetricWithPeriodSum ( icmData ) , // Period sum
211222 validatorCount,
212223 } ;
@@ -268,88 +279,127 @@ export async function GET(request: Request) {
268279 }
269280
270281 const aggregatedTxData : TimeSeriesDataPoint [ ] = [ ] ;
271- const aggregatedAddressData : TimeSeriesDataPoint [ ] = [ ] ;
282+ const aggregatedDailyAddressData : TimeSeriesDataPoint [ ] = [ ] ;
283+ const aggregatedWeeklyAddressData : TimeSeriesDataPoint [ ] = [ ] ;
284+ const aggregatedMonthlyAddressData : TimeSeriesDataPoint [ ] = [ ] ;
272285 const aggregatedICMData : ICMDataPoint [ ] = [ ] ;
273286
274287 let totalValidators = 0 ;
275288 let activeChains = 0 ;
276289 let totalTxCountAllTime = 0 ;
277- let totalActiveAddressesAllTime = 0 ;
290+ let totalDailyActiveAddressesAllTime = 0 ;
291+ let totalWeeklyActiveAddressesAllTime = 0 ;
292+ let totalMonthlyActiveAddressesAllTime = 0 ;
278293 let totalICMMessagesAllTime = 0 ;
279294
280- const dateMap = new Map < string , { tx : number ; addresses : number ; icm : number } > ( ) ;
295+ const dateMaps = {
296+ tx : new Map < string , number > ( ) ,
297+ daily : new Map < string , number > ( ) ,
298+ weekly : new Map < string , number > ( ) ,
299+ monthly : new Map < string , number > ( ) ,
300+ icm : new Map < string , number > ( ) ,
301+ } ;
281302
282303 chainMetrics . forEach ( chain => {
283304 if ( typeof chain . validatorCount === 'number' ) {
284305 totalValidators += chain . validatorCount ;
285306 }
286307
287308 const hasTx = chain . txCount . data . length > 0 && typeof chain . txCount . current_value === 'number' && chain . txCount . current_value > 0 ;
288- const hasAddresses = chain . activeAddresses . data . length > 0 && typeof chain . activeAddresses . current_value === 'number' && chain . activeAddresses . current_value > 0 ;
309+ const hasAddresses = chain . activeAddresses . daily . data . length > 0 && typeof chain . activeAddresses . daily . current_value === 'number' && chain . activeAddresses . daily . current_value > 0 ;
289310
290311 if ( hasTx || hasAddresses ) { activeChains ++ ; }
291312
292313 chain . txCount . data . forEach ( point => {
293314 const date = point . date ;
294315 const value = typeof point . value === 'number' ? point . value : 0 ;
295- const current = dateMap . get ( date ) || { tx : 0 , addresses : 0 , icm : 0 } ;
296- current . tx += value ;
297- dateMap . set ( date , current ) ;
316+ const current = dateMaps . tx . get ( date ) || 0 ;
317+ dateMaps . tx . set ( date , current + value ) ;
298318 totalTxCountAllTime += value ;
299319 } ) ;
300320
301- chain . activeAddresses . data . forEach ( point => {
321+ chain . activeAddresses . daily . data . forEach ( point => {
302322 const date = point . date ;
303323 const value = typeof point . value === 'number' ? point . value : 0 ;
304- const current = dateMap . get ( date ) || { tx : 0 , addresses : 0 , icm : 0 } ;
305- current . addresses += value ;
306- dateMap . set ( date , current ) ;
307- totalActiveAddressesAllTime += value ;
324+ const current = dateMaps . daily . get ( date ) || 0 ;
325+ dateMaps . daily . set ( date , current + value ) ;
326+ totalDailyActiveAddressesAllTime += value ;
327+ } ) ;
328+
329+ chain . activeAddresses . weekly . data . forEach ( point => {
330+ const date = point . date ;
331+ const value = typeof point . value === 'number' ? point . value : 0 ;
332+ const current = dateMaps . weekly . get ( date ) || 0 ;
333+ dateMaps . weekly . set ( date , current + value ) ;
334+ totalWeeklyActiveAddressesAllTime += value ;
335+ } ) ;
336+
337+ chain . activeAddresses . monthly . data . forEach ( point => {
338+ const date = point . date ;
339+ const value = typeof point . value === 'number' ? point . value : 0 ;
340+ const current = dateMaps . monthly . get ( date ) || 0 ;
341+ dateMaps . monthly . set ( date , current + value ) ;
342+ totalMonthlyActiveAddressesAllTime += value ;
308343 } ) ;
309344
310345 chain . icmMessages . data . forEach ( point => {
311346 const date = point . date ;
312- const current = dateMap . get ( date ) || { tx : 0 , addresses : 0 , icm : 0 } ;
313- current . icm += point . messageCount ;
314- dateMap . set ( date , current ) ;
347+ const current = dateMaps . icm . get ( date ) || 0 ;
348+ dateMaps . icm . set ( date , current + point . messageCount ) ;
315349 totalICMMessagesAllTime += point . messageCount ;
316350 } ) ;
317351 } ) ;
318352
319- Array . from ( dateMap . entries ( ) ) . forEach ( ( [ date , values ] ) => {
353+ Array . from ( dateMaps . tx . entries ( ) ) . forEach ( ( [ date , value ] ) => {
320354 const timestamp = Math . floor ( new Date ( date ) . getTime ( ) / 1000 ) ;
321- aggregatedTxData . push ( {
322- timestamp,
323- value : values . tx ,
324- date
325- } ) ;
355+ aggregatedTxData . push ( { timestamp, value, date } ) ;
356+ } ) ;
326357
327- aggregatedAddressData . push ( {
328- timestamp,
329- value : values . addresses ,
330- date
331- } ) ;
358+ Array . from ( dateMaps . daily . entries ( ) ) . forEach ( ( [ date , value ] ) => {
359+ const timestamp = Math . floor ( new Date ( date ) . getTime ( ) / 1000 ) ;
360+ aggregatedDailyAddressData . push ( { timestamp, value, date } ) ;
361+ } ) ;
362+
363+ Array . from ( dateMaps . weekly . entries ( ) ) . forEach ( ( [ date , value ] ) => {
364+ const timestamp = Math . floor ( new Date ( date ) . getTime ( ) / 1000 ) ;
365+ aggregatedWeeklyAddressData . push ( { timestamp, value, date } ) ;
366+ } ) ;
367+
368+ Array . from ( dateMaps . monthly . entries ( ) ) . forEach ( ( [ date , value ] ) => {
369+ const timestamp = Math . floor ( new Date ( date ) . getTime ( ) / 1000 ) ;
370+ aggregatedMonthlyAddressData . push ( { timestamp, value, date } ) ;
371+ } ) ;
332372
373+ Array . from ( dateMaps . icm . entries ( ) ) . forEach ( ( [ date , messageCount ] ) => {
374+ const timestamp = Math . floor ( new Date ( date ) . getTime ( ) / 1000 ) ;
333375 aggregatedICMData . push ( {
334376 timestamp,
335377 date,
336- messageCount : values . icm ,
378+ messageCount,
337379 incomingCount : 0 ,
338380 outgoingCount : 0
339381 } ) ;
340382 } ) ;
341383
342384 // Sort by timestamp descending
343385 aggregatedTxData . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
344- aggregatedAddressData . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
386+ aggregatedDailyAddressData . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
387+ aggregatedWeeklyAddressData . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
388+ aggregatedMonthlyAddressData . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
345389 aggregatedICMData . sort ( ( a , b ) => b . timestamp - a . timestamp ) ;
346390
347391 // Create aggregated metrics using period sum methods
348392 const totalTxMetric = createTimeSeriesMetricWithPeriodSum ( aggregatedTxData ) ;
349393 totalTxMetric . current_value = totalTxCountAllTime ;
350394
351- const totalAddressMetric = createTimeSeriesMetricWithPeriodSum ( aggregatedAddressData ) ;
352- totalAddressMetric . current_value = totalActiveAddressesAllTime ;
395+ const totalDailyAddressMetric = createTimeSeriesMetric ( aggregatedDailyAddressData ) ;
396+ totalDailyAddressMetric . current_value = totalDailyActiveAddressesAllTime ;
397+
398+ const totalWeeklyAddressMetric = createTimeSeriesMetric ( aggregatedWeeklyAddressData ) ;
399+ totalWeeklyAddressMetric . current_value = totalWeeklyActiveAddressesAllTime ;
400+
401+ const totalMonthlyAddressMetric = createTimeSeriesMetric ( aggregatedMonthlyAddressData ) ;
402+ totalMonthlyAddressMetric . current_value = totalMonthlyActiveAddressesAllTime ;
353403
354404 const totalICMMetric = createICMMetricWithPeriodSum ( aggregatedICMData ) ;
355405 totalICMMetric . current_value = totalICMMessagesAllTime ;
@@ -358,7 +408,11 @@ export async function GET(request: Request) {
358408 chains : chainMetrics ,
359409 aggregated : {
360410 totalTxCount : totalTxMetric ,
361- totalActiveAddresses : totalAddressMetric ,
411+ totalActiveAddresses : {
412+ daily : totalDailyAddressMetric ,
413+ weekly : totalWeeklyAddressMetric ,
414+ monthly : totalMonthlyAddressMetric ,
415+ } ,
362416 totalICMMessages : totalICMMetric ,
363417 totalValidators,
364418 activeChains
0 commit comments