Skip to main content

Data Wallet (OpenID4VC) SDKs

The following steps outline how developers can integrate EUDI Wallet OpenID4VC SDKs for Android and iOS into their existing Android or iOS applications.

Step 01: Installation

Use the following code to add depedency:

settings.gradle
repositories {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
mavenCentral()
maven { url 'https://jitpack.io' }
}
}
build.gradle
dependencies {
implementation 'com.github.decentralised-dataexchange:eudi-wallet-oidc-android:2024.5.1'
}

Additional dependencies:

build.gradle
dependencies {
implementation("com.nimbusds:nimbus-jose-jwt:9.21")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
}

Verifiable Credential Issuance Functions

Initialise

The following function allows you to initialise the issuance service class with the required parameters.

MyActivity.kt
val issueService = IssueService()

Resolve Credential offer

This function allows resolving the credential offer received from the issuer. A credential offer may have a grant specified. It can be either:

  1. Pre-Authorized code flow
  2. Authorization code flow
MyActivity.kt
val credentialOffer = issueService.resolveCredentialOffer(data)

Issuer Metadata

This function allows to perform discovery and fetch issuer metadata.

MyActivity.kt
val discoveryService = DiscoveryService()
val issuerMetadata= discoveryService.getIssuerConfig("${credentialOffer?.credentialIssuer}/.well-known/openid-credential-issuer")

Authorisation Server Metadata

This function allows to perform discovery and fetch authorisation server metadata.

MyActivity.kt
val authorisationServerMetadata = DiscoveryService().getAuthConfig("${issuerMetadata?.issuerConfig?.authorizationServer}/.well-known/openid-configuration"
)

Authorisation Request

This section outlines the steps to perform the authorization request for credential issuance.

Step 1: Identify the Code Flow

Determine whether the issuance is an Authorized code flow or Pre-authorized code flow using the following code:

MyActivity.kt
val isPreAuthFlow = credentialOffer.grants?.preAuthorizationCode != null

Step 2: Create DID and Public/Private Key Pair

Create Public/Private Key Pair

The following function allows to create a random public/private key pair and Json Web Key (JWK) for the same:

MyActivity.kt
val jwk = DIDService().createJWK(cryptographicAlgorithm = CryptographicAlgorithms.ES256)
Create DID

The following function allows to create a did:key identifier from a JSON Web Key (JWK).

MyActivity.kt
val did = DIDService().createDID(jwk, cryptographicAlgorithm = CryptographicAlgorithms.ES256)

Step 3: Generate Code Verifier for Proof Key for Code Exchange (PKCE)

The following function allows to create a code verifier for Proof Key for Code Exchange (PKCE):

MyActivity.kt
val codeVerifier = CodeVerifierService().generateCodeVerifier()

Step 4: Send Authorisation Request

The following function allows to send authorisation request to issuer's authorisation server endpoint and obtain the authorisation response.

MyActivity.kt
val authorisationResponse = issueService.processAuthorisationRequest(
did,
jwk,
credentialOffer,
codeVerifier,
authorisationServerMetadata?.authConfig?.authorizationEndpoint
)

val authorisationCode = Uri.parse(authorisationResponse).getQueryParameter("code")

Token Request

The following function allows to sent token request to the issuer's token endpoint and obtain the access token/refresh token pair.

MyActivity.kt
val tokenResponse= issueService.processTokenRequest(
did = did,
tokenEndPoint = authorisationServerMetadata?.authConfig?.tokenEndpoint,
code = authorisationCode,
codeVerifier = codeVerifier,
isPreAuthorisedCodeFlow = isPreAuthFlow ,
userPin = null
)

Credential Request

Credentials can be issued in two ways: InTime and Deferred.

  • InTime issuance: The credential is provided immediately as a response.
  • Deferred issuance: The credential is issued after a processing period, which can take minutes to hours.

The following function allows to sent credential request to credential endpoint using the access token and nonce obtained from the previous step:

MyActivity.kt
val credentialResponse = issueService.processCredentialRequest(did, jwk, nonce, credentialOffer, issuerMetadata?.issuerConfig, accessToken, format)

Format can be obtained from the issuerMetadata, Use

issuerService.getFormatFromIssuerConfig(issuerMetadata?.issuerConfig, <Credential type>)

In the response, you will receive the credential. Sometimes, instead of credentials, you will only receive an acceptance token. If the response contains an acceptance token, you need to follow the deferred credential flow.

Deferred Credential Request

The following function allows to sent deferred credential request to deferred credential endpoint using the acceptance token obtained from the previous step:

MyActivity.kt
val credentialResponse = issueService.processDeferredCredentialRequest(acceptanceToken, issuerMetadata.issuerConfig?.deferredCredentialEndpoint)

Verifiable Presentation Functions

Authorisation Request

This function allows to resolve the authorisation request from the verifier containing the presentation definition:

MyActivity.kt
val authorisationRequest = VerificationService().processAuthorisationRequest(data)

Authorisation Response

This function allows to send the authorisation response with VP token and presentation submission to the verifier.

Step 1: Filter the Matching Credentials against Presentation Definition

MyActivity.kt
val filteredCredentials = VerificationService().filterCredentials(<All credentials in the storage>, authorisationRequest)

Step 2: Send Authorisation Response

MyActivity.kt
val authorisationCode = VerificationService().sendVPToken(did, jwk, authorisationRequest, filteredCredentials)