getActiveValidators method
Active validators for the current (or given) epoch, parsed from each
validator's on-chain 0x3::validator::Validator contents.
Note: annualized APY is not a stored field — it must be derived from each
staking pool's exchange-rate history (a separate traversal). The raw
stakingPoolSuiBalance / poolTokenBalance needed for that are exposed.
Implementation
Future<List<ValidatorInfo>> getActiveValidators({
int? epochId,
int first = 50,
String? after,
}) async {
// The endpoint caps page size at 50; paginate internally to gather all.
const q = r'''
query ($id: UInt53, $first: Int!, $after: String) {
epoch(epochId: $id) {
validatorSet {
activeValidators(first: $first, after: $after) {
pageInfo { hasNextPage endCursor }
nodes { contents { json } }
}
}
}
}
''';
final pageSize = first > 50 ? 50 : first;
final out = <ValidatorInfo>[];
String? cursor = after;
while (true) {
final data = await transport.query(q, variables: {
if (epochId != null) 'id': epochId,
'first': pageSize,
if (cursor != null) 'after': cursor,
});
final vs = (((data['epoch'] as Map)['validatorSet']
as Map)['activeValidators'] as Map);
out.addAll((vs['nodes'] as List).map((n) => ValidatorInfo._fromJson(
(n as Map<String, dynamic>)['contents']['json']
as Map<String, dynamic>)));
final pageInfo = vs['pageInfo'] as Map<String, dynamic>;
if (pageInfo['hasNextPage'] != true) break;
cursor = pageInfo['endCursor'] as String?;
if (cursor == null) break;
}
return out;
}