decodeSessions static method

List<SessionGrant> decodeSessions(
  1. Uint8List contents
)

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,
      ),
  ];
}