@@ -19,13 +19,21 @@ import { Separator } from '~/components/Separator'
19
19
import { StatCell , StatGrid } from '~/components/StatGrid'
20
20
import { OperatorIdCell } from '~/components/Table'
21
21
import WalletPass from '~/components/WalletPass'
22
+ import {
23
+ GetStreamsDocument as GetIndexerStreamsDocument ,
24
+ GetStreamsQuery as GetIndexerStreamsQuery ,
25
+ GetStreamsQueryVariables as GetIndexerStreamsQueryVariables ,
26
+ StreamOrderBy as IndexerOrderBy ,
27
+ OrderDirection as IndexerOrderDirection ,
28
+ } from '~/generated/gql/indexer'
22
29
import { OperatorDailyBucket } from '~/generated/gql/network'
23
30
import {
24
31
getNetworkStats ,
25
32
getOperatorDailyBuckets ,
26
33
getTimestampForChartPeriod ,
27
34
} from '~/getters'
28
35
import { getDelegationStats } from '~/getters/getDelegationStats'
36
+ import { getIndexerClient } from '~/getters/getGraphClient'
29
37
import { getSponsorshipTokenInfo } from '~/getters/getSponsorshipTokenInfo'
30
38
import {
31
39
useDelegationsForWalletQuery ,
@@ -71,30 +79,125 @@ export function NetworkOverviewPage() {
71
79
function NetworkStats ( ) {
72
80
const currentChainId = useCurrentChainId ( )
73
81
74
- const { data } = useQuery ( {
82
+ const statsQuery = useQuery ( {
75
83
queryKey : [ 'networkStats' , currentChainId ] ,
76
84
async queryFn ( ) {
77
85
return getNetworkStats ( currentChainId )
78
86
} ,
79
87
} )
80
88
89
+ const operatorCountQuery = useActiveOperatorCountQuery ( )
90
+
81
91
return (
82
92
< NetworkPageSegment title = "Network stats" >
83
93
< Pad >
84
94
< StatGrid >
85
95
< StatCell label = "Total stake" >
86
- { data && (
87
- < SponsorshipDecimals abbr amount = { data . totalStake } tooltip />
96
+ { statsQuery . isLoading ? (
97
+ < > ‌</ >
98
+ ) : (
99
+ < >
100
+ { statsQuery . data ? (
101
+ < SponsorshipDecimals
102
+ abbr
103
+ amount = { statsQuery . data . totalStake }
104
+ tooltip
105
+ />
106
+ ) : (
107
+ < > N/A</ >
108
+ ) }
109
+ </ >
110
+ ) }
111
+ </ StatCell >
112
+ < StatCell label = "Sponsorships" >
113
+ { statsQuery . isLoading ? (
114
+ < > ‌</ >
115
+ ) : (
116
+ statsQuery . data ?. sponsorshipsCount ?? < > N/A</ >
117
+ ) }
118
+ </ StatCell >
119
+ < StatCell label = "Active Operators" >
120
+ { operatorCountQuery . isLoading ? (
121
+ < > ‌</ >
122
+ ) : (
123
+ operatorCountQuery . data ?? < > N/A</ >
88
124
) }
89
125
</ StatCell >
90
- < StatCell label = "Sponsorships" > { data ?. sponsorshipsCount } </ StatCell >
91
- < StatCell label = "Operators" > { data ?. operatorsCount } </ StatCell >
92
126
</ StatGrid >
93
127
</ Pad >
94
128
</ NetworkPageSegment >
95
129
)
96
130
}
97
131
132
+ function useActiveOperatorCountQuery ( ) {
133
+ const chainId = useCurrentChainId ( )
134
+
135
+ return useQuery ( {
136
+ queryKey : [ 'useActiveOperatorCountQuery' , chainId ] ,
137
+ queryFn : async ( ) => {
138
+ let cursor = '0'
139
+
140
+ const uniquenessGate : Record < string , true | undefined > = { }
141
+
142
+ let count = 0
143
+
144
+ const client = getIndexerClient ( chainId )
145
+
146
+ if ( ! client ) {
147
+ return 0
148
+ }
149
+
150
+ for ( ; ; ) {
151
+ const {
152
+ data : { streams } ,
153
+ } = await client . query <
154
+ GetIndexerStreamsQuery ,
155
+ GetIndexerStreamsQueryVariables
156
+ > ( {
157
+ fetchPolicy : 'network-only' ,
158
+ query : GetIndexerStreamsDocument ,
159
+ variables : {
160
+ first : 500 ,
161
+ orderBy : IndexerOrderBy . MessagesPerSecond ,
162
+ orderDirection : IndexerOrderDirection . Desc ,
163
+ cursor,
164
+ } ,
165
+ } )
166
+
167
+ const breakEarly = ( ( ) => {
168
+ for ( const item of streams . items ) {
169
+ if ( ! item . messagesPerSecond ) {
170
+ /**
171
+ * Make the whole stream fetching skip streams that have no
172
+ * data flowing through them.
173
+ */
174
+ return true
175
+ }
176
+
177
+ if ( ! uniquenessGate [ item . id ] ) {
178
+ if ( / ^ [ ^ / ] + \/ o p e r a t o r \/ c o o r d i n a t i o n $ / . test ( item . id ) ) {
179
+ count += 1
180
+ }
181
+ }
182
+
183
+ uniquenessGate [ item . id ] = true
184
+ }
185
+
186
+ return false
187
+ } ) ( )
188
+
189
+ if ( ! streams . cursor || breakEarly ) {
190
+ break
191
+ }
192
+
193
+ cursor = streams . cursor
194
+ }
195
+
196
+ return count
197
+ } ,
198
+ } )
199
+ }
200
+
98
201
function MyOperatorSummary ( ) {
99
202
const wallet = useWalletAccount ( )
100
203
0 commit comments