claimCredential method
Future<VerifiableCredential>
claimCredential({
- required OID4VCIClaimContext claimContext,
- String? txCode,
Claims a credential using the provided claimContext and optional txCode.
This method retrieves an access token using the credential offer and then uses that token along with a JWT (fetched from the consumer auth provider) to claim the credential.
claimContext - Contains the credential offer and issuer metadata necessary for claiming.
txCode (optional) - A transaction code that may be required by the token endpoint.
Returns a VerifiableCredential representing the claimed credential if successful.
Throws:
- TdkException if any step of the claim process fails.
- server_error: when server is unable to process the claim for some unexpected reason.
- unmatched_tx_code: when transaction code provided does not match the one issued with the credential.
- credential_offer_expired: when the credential offer has expired.
- credential_offer_claimed: when the credential has already been claimed.
- failedToClaimCredential: when an unknown error occurred.
Example:
final credential = await service.claimCredential(
claimContext: claimContext,
txCode: 'optionalTxCode',
);
Log.info('Claimed Credential: ${credential.toJson()}', component: 'YourComponent');
Implementation
@override
Future<VerifiableCredential> claimCredential({
required OID4VCIClaimContext claimContext,
String? txCode,
}) async {
_logger.info('Started claiming credential', component: _componentName);
try {
final accessTokenResponse = await _claimVerifiableCredentialApiService
.getClaimCredentialAccessToken(
offer: claimContext.credentialOffer,
tokenEndpoint: claimContext.issuerMetadata.tokenEndpoint,
transactionCode: txCode,
);
if (accessTokenResponse.statusCode != 200) {
_logger.error(
'Failed loading credential offer - ${accessTokenResponse.data}',
component: _componentName,
);
Error.throwWithStackTrace(
TdkExceptionExtension.fromError(
accessTokenResponse.data as Map<String, dynamic>,
),
StackTrace.current,
);
}
final accessTokenResponseJson =
accessTokenResponse.data as Map<String, dynamic>;
final jwt = await _consumerAuthProvider.fetchCisToken();
final credentialResponse = await _claimVerifiableCredentialApiService
.claimCredential(
accessToken: accessTokenResponseJson['access_token'] as String,
offer: claimContext.credentialOffer,
credentialEndpoint: claimContext.issuerMetadata.credentialEndpoint,
jwt: jwt,
);
if (credentialResponse.statusCode != 200) {
_logger.error(
'Failed claiming credential offer - ${credentialResponse.data}',
component: _componentName,
);
Error.throwWithStackTrace(
TdkExceptionExtension.fromError(
credentialResponse.data as Map<String, dynamic>,
),
StackTrace.current,
);
}
final credentialResponseJson =
credentialResponse.data as Map<String, dynamic>;
final credentialJson =
credentialResponseJson['credential'] as Map<String, dynamic>;
final signedCredential =
credentialJson['signedCredential'] as Map<String, dynamic>;
final vc = UniversalParser.parse(jsonEncode(signedCredential));
_logger.info('Completed claiming credential', component: _componentName);
return vc;
} catch (e, stackTrace) {
_logger.error(
'Failed claiming credential offer',
component: _componentName,
error: e,
stackTrace: stackTrace,
);
if (e is TdkException) {
rethrow;
}
if (e is DioException) {
final tdkException = e.asTdkException();
if (tdkException != null) {
Error.throwWithStackTrace(tdkException, stackTrace);
}
}
Error.throwWithStackTrace(
TdkException(
message: 'Failed to claim credential',
originalMessage: e.toString(),
code: TdkExceptionType.failedToClaimCredential.code,
),
stackTrace,
);
}
}