Skip to content

Commit

Permalink
feat: Handling credential manifest before showing Add credential Page #…
Browse files Browse the repository at this point in the history
  • Loading branch information
bibash28 committed Jul 20, 2023
1 parent 0bbeef2 commit c5a9611
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 68 deletions.
3 changes: 3 additions & 0 deletions lib/app/shared/constants/urls.dart
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ class Urls {

static const String bloometaCardUrl = 'https://issuer.talao.co/bloometa';

static const String defaultPolygonIdCardUrl =
'https://issuer.talao.co/credential-manifest/polygonid/default';

static const String kycAgeCredentialUrl =
'https://issuer.talao.co/credential-manifest/polygonid/kycagecredential';
static const String kycCountryOfResidenceUrl =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,26 @@ import 'package:altme/l10n/l10n.dart';
import 'package:altme/pin_code/pin_code.dart';
import 'package:altme/polygon_id/polygon_id.dart';
import 'package:altme/theme/theme.dart';
import 'package:credential_manifest/credential_manifest.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:polygonid/polygonid.dart';

class PolygonIdCredentialOfferPage extends StatelessWidget {
const PolygonIdCredentialOfferPage({
super.key,
required this.claims,
});

final List<ClaimEntity> claims;

static Route<dynamic> route({
required List<ClaimEntity> claims,
}) =>
MaterialPageRoute<void>(
builder: (context) => PolygonIdCredentialOfferPage(
claims: claims,
),
static Route<dynamic> route() => MaterialPageRoute<void>(
builder: (context) => const PolygonIdCredentialOfferPage(),
settings: const RouteSettings(name: '/PolygonIdCredentialOffer'),
);

@override
Widget build(BuildContext context) {
final l10n = context.l10n;

final polygonIdCubitState = context.read<PolygonIdCubit>().state;

return BasePage(
title: l10n.credentialReceiveTitle,
useSafeArea: true,
Expand All @@ -47,12 +41,12 @@ class PolygonIdCredentialOfferPage extends StatelessWidget {
),
const SizedBox(height: 30),
ListView.builder(
itemCount: claims.length,
itemCount: polygonIdCubitState.claims!.length,
padding: EdgeInsets.zero,
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int i) {
final jsonCredential = claims[i].info;
final jsonCredential = polygonIdCubitState.claims![i].info;
final credentialPreview = Credential.fromJson(jsonCredential);

Widget widget;
Expand Down Expand Up @@ -84,10 +78,40 @@ class PolygonIdCredentialOfferPage extends StatelessWidget {
);
} else if (credentialSubjectType ==
CredentialSubjectType.civicPassCredential) {
widget = const CredentialBaseWidget(
final polygonIdCubitState =
context.read<PolygonIdCubit>().state;
final DisplayMapping? titleDisplayMapping =
polygonIdCubitState.credentialManifests![i]
.outputDescriptors?.first.display?.title;

var title = '';

if (titleDisplayMapping is DisplayMappingText) {
title = titleDisplayMapping.text;
}

if (titleDisplayMapping is DisplayMappingPath) {
title = titleDisplayMapping.fallback ?? '';
}

final DisplayMapping? subTitleDisplayMapping =
polygonIdCubitState.credentialManifests![i]
.outputDescriptors?.first.display?.subtitle;

var subTitle = '';

if (subTitleDisplayMapping is DisplayMappingText) {
subTitle = subTitleDisplayMapping.text;
}

if (subTitleDisplayMapping is DisplayMappingPath) {
subTitle = subTitleDisplayMapping.fallback ?? '';
}
widget = CredentialBaseWidget(
title: title,
cardBackgroundImagePath: ImageStrings.civicPassCard,
issuerName: 'CIVIC',
value: '',
value: subTitle,
);
} else {
widget = DefaultCredentialListWidget(
Expand Down Expand Up @@ -127,9 +151,7 @@ class PolygonIdCredentialOfferPage extends StatelessWidget {
Navigator.of(context).push<void>(
PinCodePage.route(
isValidCallback: () {
context.read<PolygonIdCubit>().addPolygonIdCredentials(
claims: claims,
);
context.read<PolygonIdCubit>().addPolygonIdCredentials();
},
restrictToBack: false,
),
Expand Down
105 changes: 63 additions & 42 deletions lib/polygon_id/cubit/polygon_id_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -267,13 +267,59 @@ class PolygonIdCubit extends Cubit<PolygonIdState> {
}
} else if (iden3MessageEntity.messageType ==
Iden3MessageType.credentialOffer) {
log.i('get claims');
emit(
state.copyWith(
status: AppStatus.loading,
polygonAction: PolygonIdAction.offer,
),
);
try {
final List<ClaimEntity> claims = await getClaims(
iden3MessageEntity: iden3MessageEntity,
);

final List<CredentialManifest> credentialManifests =
<CredentialManifest>[];

for (final claimEntity in claims) {
dynamic response;

// Try to get Credential manifest for kycAgeCredential
// and kycCountryOfResidence and proofOfTwitterStatsUrl
if (claimEntity.type == CredentialSubjectType.kycAgeCredential.name) {
response = await client.get(Urls.kycAgeCredentialUrl);
} else if (claimEntity.type ==
CredentialSubjectType.kycCountryOfResidence.name) {
response = await client.get(Urls.kycCountryOfResidenceUrl);
} else if (claimEntity.type ==
CredentialSubjectType.proofOfTwitterStats.name) {
response = await client.get(Urls.proofOfTwitterStatsUrl);
} else if (claimEntity.type ==
CredentialSubjectType.civicPassCredential.name) {
response = await client.get(Urls.civicPassCredentialUrl);
} else {
response = await client.get(Urls.defaultPolygonIdCardUrl);
}

final CredentialManifest credentialManifest =
CredentialManifest.fromJson(response as Map<String, dynamic>);

credentialManifests.add(credentialManifest);
}

if (claims.length != credentialManifests.length) {
throw Exception();
}

log.i('get claims');
emit(
state.copyWith(
status: AppStatus.loading,
polygonAction: PolygonIdAction.offer,
claims: claims,
credentialManifests: credentialManifests,
),
);
} catch (e) {
log.e('can not get the credntials manifest for polygon error: $e');
throw ResponseMessage(
ResponseString.RESPONSE_STRING_SOMETHING_WENT_WRONG_TRY_AGAIN_LATER,
);
}
} else if (iden3MessageEntity.messageType ==
Iden3MessageType.proofContractInvokeRequest) {
log.i('contractFunctionCall');
Expand Down Expand Up @@ -395,14 +441,15 @@ class PolygonIdCubit extends Cubit<PolygonIdState> {
return claims;
}

Future<void> addPolygonIdCredentials({
required List<ClaimEntity> claims,
}) async {
Future<void> addPolygonIdCredentials() async {
try {
log.i('add Claims');
emit(state.copyWith(status: AppStatus.loading));
for (final claim in claims) {
await addToList(claim);
for (int i = 0; i < state.claims!.length; i++) {
await addToList(
claimEntity: state.claims![i],
credentialManifest: state.credentialManifests![i],
);
}
emit(state.copyWith(status: AppStatus.goBack));
} catch (e) {
Expand All @@ -424,39 +471,13 @@ class PolygonIdCubit extends Cubit<PolygonIdState> {
}
}

Future<void> addToList(ClaimEntity claimEntity) async {
Future<void> addToList({
required ClaimEntity claimEntity,
required CredentialManifest credentialManifest,
}) async {
final jsonCredential = claimEntity.info;
final credentialPreview = Credential.fromJson(jsonCredential);

CredentialManifest? credentialManifest;

try {
// Try to get Credential manifest for kycAgeCredential
// and kycCountryOfResidence and proofOfTwitterStatsUrl
if (claimEntity.type == CredentialSubjectType.kycAgeCredential.name) {
final response = await client.get(Urls.kycAgeCredentialUrl);
credentialManifest =
CredentialManifest.fromJson(response as Map<String, dynamic>);
} else if (claimEntity.type ==
CredentialSubjectType.kycCountryOfResidence.name) {
final response = await client.get(Urls.kycCountryOfResidenceUrl);
credentialManifest =
CredentialManifest.fromJson(response as Map<String, dynamic>);
} else if (claimEntity.type ==
CredentialSubjectType.proofOfTwitterStats.name) {
final response = await client.get(Urls.proofOfTwitterStatsUrl);
credentialManifest =
CredentialManifest.fromJson(response as Map<String, dynamic>);
} else if (claimEntity.type ==
CredentialSubjectType.civicPassCredential.name) {
final response = await client.get(Urls.civicPassCredentialUrl);
credentialManifest =
CredentialManifest.fromJson(response as Map<String, dynamic>);
}
} catch (e) {
log.e('can not get the credntials manifest for polygon error: $e');
}

final credentialModel = CredentialModel(
id: claimEntity.id,
image: 'image',
Expand Down
12 changes: 10 additions & 2 deletions lib/polygon_id/cubit/polygon_id_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ class PolygonIdState extends Equatable {
this.message,
this.loadingText,
this.scannedResponse,
this.claims,
this.credentialManifests,
});

factory PolygonIdState.fromJson(Map<String, dynamic> json) =>
Expand All @@ -21,12 +23,13 @@ class PolygonIdState extends Equatable {
final MessageHandler? loadingText;
final bool isInitialised;
final String? scannedResponse;
final List<ClaimEntity>? claims;
final List<CredentialManifest>? credentialManifests;

PolygonIdState error({required StateMessage message}) {
return PolygonIdState(
return copyWith(
status: AppStatus.error,
message: message,
scannedResponse: scannedResponse,
);
}

Expand All @@ -38,6 +41,8 @@ class PolygonIdState extends Equatable {
MessageHandler? loadingText,
Route<dynamic>? route,
String? scannedResponse,
List<ClaimEntity>? claims,
List<CredentialManifest>? credentialManifests,
}) {
return PolygonIdState(
status: status,
Expand All @@ -46,6 +51,8 @@ class PolygonIdState extends Equatable {
loadingText: loadingText,
isInitialised: isInitialised ?? this.isInitialised,
scannedResponse: scannedResponse ?? this.scannedResponse,
claims: claims ?? this.claims,
credentialManifests: credentialManifests ?? this.credentialManifests,
);
}

Expand All @@ -59,5 +66,6 @@ class PolygonIdState extends Equatable {
isInitialised,
scannedResponse,
loadingText,
credentialManifests,
];
}
7 changes: 1 addition & 6 deletions lib/splash/bloclisteners/blocklisteners.dart
Original file line number Diff line number Diff line change
Expand Up @@ -510,14 +510,9 @@ final polygonIdBlocListener = BlocListener<PolygonIdCubit, PolygonIdState>(

if (state.polygonAction == PolygonIdAction.offer) {
try {
final Iden3MessageEntity iden3MessageEntity = await polygonIdCubit
.getIden3Message(message: state.scannedResponse!);
final List<ClaimEntity> claims = await polygonIdCubit.getClaims(
iden3MessageEntity: iden3MessageEntity,
);
LoadingView().hide();
await Navigator.of(context)
.push<void>(PolygonIdCredentialOfferPage.route(claims: claims));
.push<void>(PolygonIdCredentialOfferPage.route());
} catch (e) {
final l10n = context.l10n;
LoadingView().hide();
Expand Down

0 comments on commit c5a9611

Please sign in to comment.