claimCredential method

  1. @override
Future<VerifiableCredential> claimCredential({
  1. required OID4VCIClaimContext claimContext,
  2. 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,
    );
  }
}