Description
Credentials currently have no expiration concept. Many educational credentials (certifications, licenses) should expire after a set period and require renewal. We need expiration timestamps on credentials with on-chain status that automatically reflects expiration.
Definition of Done
- Optional
expires_at: Option<u64> field added to the credential struct in credentials.rs
issue_credential accepts optional expiration timestamp; if None, credential never expires
- Credential status enum updated:
Active, Revoked (from related issue), Expired
verify_credential checks expiration: if expires_at < current_ledger_timestamp, returns Expired status
- No automatic state change transaction required — expiration is checked at read time (lazy evaluation for gas efficiency)
get_credential_status(id) function that returns (Active/Expired/Revoked) and the expired_at timestamp if applicable
- Renewal:
renew_credential(id, new_expires_at) function callable by original issuer, updates expiration
- Renewal emits
CredentialRenewed event
- Storage optimization: expiration stored as optional packed timestamp
- Unit tests: issue with expiration, issue without expiration, verify after expiration, renew credential, renew non-expired, unauthorized renewal
Files to Modify
contracts/src/credentials.rs (add expires_at field, CredentialStatus enum, renew function)
contracts/src/credential_registry.rs (integrate expiration in issue/verify flow)
contracts/src/credentials_test.rs (or test module)
contracts/src/event_logger.rs (add CredentialRenewed event)
Acceptance Criteria
Description
Credentials currently have no expiration concept. Many educational credentials (certifications, licenses) should expire after a set period and require renewal. We need expiration timestamps on credentials with on-chain status that automatically reflects expiration.
Definition of Done
expires_at: Option<u64>field added to the credential struct incredentials.rsissue_credentialaccepts optional expiration timestamp; if None, credential never expiresActive,Revoked(from related issue),Expiredverify_credentialchecks expiration: ifexpires_at < current_ledger_timestamp, returnsExpiredstatusget_credential_status(id)function that returns (Active/Expired/Revoked) and the expired_at timestamp if applicablerenew_credential(id, new_expires_at)function callable by original issuer, updates expirationCredentialRenewedeventFiles to Modify
contracts/src/credentials.rs(add expires_at field, CredentialStatus enum, renew function)contracts/src/credential_registry.rs(integrate expiration in issue/verify flow)contracts/src/credentials_test.rs(or test module)contracts/src/event_logger.rs(add CredentialRenewed event)Acceptance Criteria
expires_at = block_ts + 1_yearshowsActivewhen verified within 1 yearExpiredwhen verified after 1 yearActiveindefinitelyrenew_credential(id, block_ts + 2_years)extends expiration; verification now showsActiveagainrenew_credentialfails with authorization errorCredentialRenewedevent includes credential ID, old expiration, new expirationverify_credentialwith and without expiration check