decodeSessions static method
Decode an Account's stored grants from the raw BCS content of its
DataKey<SessionsApp> dynamic FIELD object — the whole
Field<DataKey<SessionsApp>, SessionsData>, as the core API returns
it, not the inner SessionsData. Get the id from
deriveSessionsFieldId.
There is no bulk on-chain read — sessionExpirationMs answers one address at a time — so listing grants means fetching that field and decoding it here. Note the field hangs off the DERIVED ACCOUNT address, not the wrapper address; they are different objects.
Expired grants are never pruned automatically and keep occupying slots, so callers managing the MAX_SESSIONS_PER_ACCOUNT cap should list, drop anything already expired, and revoke before granting again.
Implementation
static List<SessionGrant> decodeSessions(Uint8List contents) {
// Assert full consumption: re-serializing and comparing lengths turns
// both truncation and trailing junk into a throw, so "no grants" can
// only ever mean no grants.
final field = _sessionsDataField.parse(contents) as Map;
final reencoded = _sessionsDataField.serialize(field).toBytes();
if (reencoded.length != contents.length) {
throw ValidationError(
'sessions field is ${contents.length} bytes but its contents '
'encode to ${reencoded.length}; the bytes are truncated or carry '
'trailing data');
}
final entries =
((field['value'] as Map)['sessions'] as Map)['contents'] as List;
return [
for (final entry in entries.cast<Map>())
SessionGrant(
session: entry['key'] as String,
expiresAtMs: entry['value'] as BigInt,
),
];
}