OpenId4VciProtocolClient

class OpenId4VciProtocolClient @JvmOverloads constructor(val vciClient: OpenId4VciClient = OpenId4VciClient(proofCreators = listOf(JwtProofCreator(EphemeralKeyWithoutCert()))), val oauth2Client: OAuth2ProtocolClient = OAuth2ProtocolClient(oAuth2Client = OAuth2Client()), issuerMetadataValidator: IssuerMetadataValidator = IssuerMetadataValidator())(source)

Implements the client side of OpenID for Verifiable Credential Issuance 1.0 from 2025-09-16, without sending any HTTP request itself: every call returns an HttpExchange, whose requests the caller sends with any HTTP stack. The KDoc of each method lists the ProtocolRequests its exchange sends.

The caller runs the exchanges of a flow in order, using oauth2Client for the authorization server, and vciClient for the credential requests:

DPoP proofs and nonces for the credential issuer are handled by oauth2Client.

Constructors

Link copied to clipboard
constructor(vciClient: OpenId4VciClient = OpenId4VciClient(proofCreators = listOf(JwtProofCreator(EphemeralKeyWithoutCert()))), oauth2Client: OAuth2ProtocolClient = OAuth2ProtocolClient(oAuth2Client = OAuth2Client()), issuerMetadataValidator: IssuerMetadataValidator = IssuerMetadataValidator())

Properties

Link copied to clipboard

Implements OAuth 2.0 with the authorization server, and authenticates requests to the credential issuer.

Link copied to clipboard

Implements OID4VCI protocol, i.e. creates credential requests with proofs of possession for the credential key material, and parses the credential responses.

Functions

Link copied to clipboard
suspend fun createCredential(metadata: IssuerMetadata, credentialConfigurationId: String, clientNonce: String? = null): KmmResult<OpenId4VciClient.CredentialRequest>

Creates the credential request for exactly one credential with OpenId4VciClient.createCredential, whose proof JWT names the client_id of oauth2Client as the issuer. Send it with credentialRequest.

Creates the credential request for request, prepared with prepareCredentialRequests, with OpenId4VciClient.createCredential, whose proof JWT names the client_id of oauth2Client as the issuer (OID4VCI 1.0, Appendix F.1). Create it right before sending it with credentialRequest, with a fresh clientNonce from nonceRequest, as the credential issuer may accept each c_nonce only once (13.8).

suspend fun createCredential(tokenResponse: TokenResponseParameters, metadata: IssuerMetadata, credentialFormat: SupportedCredentialFormat, clientNonce: String? = null, previouslyRequestedScope: String? = null): KmmResult<Collection<OpenId4VciClient.CredentialRequest>>

Creates the credential requests for tokenResponse with OpenId4VciClient.createCredential, whose proof JWTs name the client_id of oauth2Client as the issuer, as OID4VCI 1.0 Appendix F.1 requires. Send each one with credentialRequest.

Link copied to clipboard

Sends request, as created by createCredential, to the IssuerMetadata.credentialEndpointUrl with the access token from tokenResponse, and decodes the (possibly encrypted) response in credentialFormat with OpenId4VciClient.decodeCredentialResponse. Validates nothing: prepare the storage of each ReceivedCredential with ReceivedCredential.prepareCredentialStorage.

Link copied to clipboard

Whether throwable, the failure of a credentialRequest, is the error invalid_nonce of the credential issuer, which rejected the c_nonce of a proof, so that the wallet "should retrieve a new c_nonce value" (OpenID4VCI 1.0, 8.3.1.2) and create the request again.

Link copied to clipboard

Loads the CredentialOffer from input, which is either a JSON-encoded credential offer, or a credential offer URL with an embedded credential_offer (by value) or a credential_offer_uri (by reference). The resource at credential_offer_uri is the JSON-encoded credential offer, see CredentialOfferUrlParameters; another credential offer URL in its place is rejected.

Link copied to clipboard

Loads the unsigned IssuerMetadata from credentialIssuer, see WellKnownPaths.CredentialIssuer, asking for application/json (OpenID4VCI 1.0, 12.2.2). Fails if their credential_issuer is not credentialIssuer (12.2.4). To load signed metadata, see the overload with a policy.

Loads the metadata of credentialIssuer, see WellKnownPaths.CredentialIssuer, asking for signed metadata (application/jwt) over unsigned ones (application/json), which the credential issuer has to support (OpenID4VCI 1.0, 12.2.2). Takes the media type of the response from its Content-Type:

Link copied to clipboard

Requests a fresh c_nonce from IssuerMetadata.nonceEndpointUrl, to be used in createCredential, or null if the credential issuer has no nonce endpoint. The DPoP-Nonce of the response, if any, is used by oauth2Client for the DPoP proofs of the following credentialRequests.

Link copied to clipboard

Parses the metadata of loaded and returns a list of CredentialIdentifierInfo, each with the credential issuer validated from signed metadata, see LoadedIssuerMetadata.Signed. Fails for signed metadata that have been rejected, see their report.

Parses issuerMetadata and returns a list of CredentialIdentifierInfo, with the issuer validated from signed metadata, if any.

Link copied to clipboard

Parses the metadata of loaded like parseCredentialMetadata, but also for signed metadata that have been rejected, e.g. as their signer is not trusted, using LoadedIssuerMetadata.Signed.untrustedMetadata without a validated credential issuer. Such metadata are no more trustworthy than unsigned ones: use this only to continue after showing the report to the user. Fails for signed metadata whose signature or subject did not pass.

Link copied to clipboard
fun prepareCredentialRequests(metadata: IssuerMetadata, tokenResponse: TokenResponseParameters, credentialFormats: Set<SupportedCredentialFormat>, previouslyRequestedScope: String? = null): KmmResult<Collection<OpenId4VciClient.PreparedCredentialRequest>>

Prepares the credential requests the access token of tokenResponse grants for the credentials of credentialFormats, with OpenId4VciClient.prepareCredentialRequests: one per credential, each with the configuration its proof and response depend on. Create each one with createCredential right before sending it.

Link copied to clipboard

Resolves the CredentialScheme of credentialFormat from the registered schemes, see AttributeIndex.

Link copied to clipboard
fun selectAuthorizationServer(issuerMetadata: IssuerMetadata, credentialIssuer: String): String

The authorization server to use for issuerMetadata, i.e. the first entry of IssuerMetadata.authorizationServers, or credentialIssuer itself.