Files
sxchnge/frontend/packages/sxchnge_kyc/lib/src/models/identity.dart
T

79 lines
1.9 KiB
Dart

import 'dart:typed_data';
enum IdentityStatus { unverified, pending, approved, changesRequested, denied }
enum ReviewReason {
passportUnreadable,
selfieUnreadable,
passportExpired,
unableToVerify,
}
enum PhotoKind { passport, selfie }
enum KycError {
unavailable,
internal,
permission,
format,
tooLarge,
unreadable,
tooSmall,
incomplete,
sessionExpired,
rateLimited,
conflict,
}
class KycException implements Exception {
const KycException(this.code);
final KycError code;
}
class Identity {
const Identity({
required this.status,
this.reason,
this.submissionId,
this.simulated = false,
this.profile = const IdentityProfile(),
this.upgradePending = false,
});
final IdentityStatus status;
final ReviewReason? reason;
final String? submissionId;
final bool simulated;
final IdentityProfile profile;
final bool upgradePending;
bool get canSubmit =>
status == IdentityStatus.unverified ||
status == IdentityStatus.changesRequested;
}
/// Customer assertions awaiting human review, distinct from a verified identity.
class IdentityProfile {
const IdentityProfile({
this.fullName = '',
this.dateOfBirth = '',
this.residenceCountry = '',
});
final String fullName, dateOfBirth, residenceCountry;
bool get isComplete {
final date = DateTime.tryParse(dateOfBirth);
return fullName.trim().isNotEmpty &&
fullName.length <= 200 &&
RegExp(r'^\d{4}-\d{2}-\d{2}$').hasMatch(dateOfBirth) &&
date != null &&
date.toIso8601String().startsWith(dateOfBirth) &&
date.isBefore(DateTime.now()) &&
RegExp(r'^[A-Z]{2}$').hasMatch(residenceCountry);
}
}
/// Ephemeral image data only. Never serialize this model into storage or telemetry.
class Photo {
Photo(Uint8List bytes)
: bytes = Uint8List.fromList(bytes).asUnmodifiableView();
final Uint8List bytes;
}