---
id: data-wallet-openID4vc-sdks
title: Data Wallet (OpenID4VC) SDKs
description: Integrate EUDI Wallet OpenID4VC SDKs for Android and iOS to enable credential issuance and verification using OpenID4VCI and OpenID4VP.
keywords: [Data Wallet, OpenID4VC, OpenID4VCI, OpenID4VP, Android SDK, iOS SDK, EUDI Wallet, verifiable credentials, credential issuance]
hide_title: false
sidebar_label: OpenID4VC SDKs
slug: /data-wallet-openID4vc-sdks/
---

> **Build this with an AI coding agent.** Install the iGrant.io Agent Skills, then ask your agent to build the integration:
>
> ```bash
> npx skills add L3-iGrant/skills
> ```

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

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:

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```groovy showLineNumbers title="settings.gradle"
repositories {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        mavenCentral()
        maven { url 'https://jitpack.io' }
    }
}
```

```groovy showLineNumbers title="build.gradle"
dependencies {
    implementation 'com.github.decentralised-dataexchange:eudi-wallet-oidc-android:2024.5.1'
}
```

Additional dependencies:

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

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```
Follow the instructions below to add the SDK to your iOS project:

1. File > Swift Packages > Add Package Dependency
2. Enter the URL of the package: https://github.com/decentralised-dataexchange/eudi-wallet-oidc-ios and click Next.
3. Choose the version or branch you want and click Next.
4. Select the target to which you want to add the package and click Finish.

```mdx-code-block
</TabItem>
</Tabs>
```

## Verifiable Credential Issuance Functions

### Initialise

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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val issueService = IssueService()
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

Import the EUDI wallet SDK as follows:

```swift showLineNumbers title="MyViewController.swift"
import eudiWalletOidcIos
```

To create instance of an issuance service, use the following function:

```swift showLineNumbers title="MyViewController.swift"
let keyHandler = CryptoKitHandler()
let issueService = eudiWalletOidcIos.IssueService(keyHandler: keyHandler)
```
> **_NOTE:_**  The classes in which the functions are implemented should conform to NSObject.

```mdx-code-block
</TabItem>
</Tabs>
```

### 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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val credentialOffer = issueService.resolveCredentialOffer(data)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let credentialOffer = try await issueService?.resolveCredentialOffer(credentialOffer:data)
```

```mdx-code-block
</TabItem>
</Tabs>
```

### Issuer Metadata

This function allows to perform discovery and fetch issuer metadata.

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

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

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let issuerMetadata = try await eudiWalletOidcIos.DiscoveryService.shared.getIssuerConfig(credentialIssuerWellKnownURI: credentialOffer.credentialIssuer)
```
```mdx-code-block
</TabItem>
</Tabs>
```

### Authorisation Server Metadata

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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

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

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let authorisationServerMetadata = try? await eudiWalletOidcIos.DiscoveryService.shared.getAuthConfig(authorisationServerWellKnownURI: issuerMetadata.authorizationServer)
```

```mdx-code-block
</TabItem>
</Tabs>
```

### 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:

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val isPreAuthFlow = credentialOffer.grants?.preAuthorizationCode != null
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let isPreAuthFlow = credentialOffer.grants?.urnIETFParamsOauthGrantTypePreAuthorizedCode
```

```mdx-code-block
</TabItem>
</Tabs>
```

#### 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:

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val jwk = DIDService().createJWK(cryptographicAlgorithm = CryptographicAlgorithms.ES256)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let jwk = await eudiWalletOidcIos.DidService.shared.createJWK(keyHandler: keyHandler)
```

```mdx-code-block
</TabItem>
</Tabs>
```

##### Create DID

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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val did = DIDService().createDID(jwk, cryptographicAlgorithm = CryptographicAlgorithms.ES256)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let did = await didKeyHandler.shared.createDID(jwk: jwk.0)
```

```mdx-code-block
</TabItem>
</Tabs>
```

#### 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):

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val codeVerifier = CodeVerifierService().generateCodeVerifier()
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let codeVerifier = codeVerifierHandler.shared.generateCodeVerifier()
```

```mdx-code-block
</TabItem>
</Tabs>
```

#### Step 4: Send Authorisation Request

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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val authorisationResponse = issueService.processAuthorisationRequest(
   did,
   jwk,
   credentialOffer,
   codeVerifier,
   authorisationServerMetadata?.authConfig?.authorizationEndpoint
)

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

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let authorisationCode =  await issueService?.processAuthorisationRequest(did: did, secureKey: jwk.1, credentialOffer: credentialOffer, codeVerifier: codeVerifier, authServer: authorisationServerMetadata)
```

```mdx-code-block
</TabItem>
</Tabs>
```

### Token Request

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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

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

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let tokenResponse = await issueService?.processTokenRequest(did: did, tokenEndPoint: authorisationServerMetadata.tokenEndpoint, code: code , codeVerifier: codeVerifier, isPreAuthorisedCodeFlow: false, userPin: nil)
```

```mdx-code-block
</TabItem>
</Tabs>
```

### 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:

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="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>)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let credentialResponse = await issueService?.processCredentialRequest(did: did, secureKey: jwk.1, nonce: tokenResponse.cNonce, credentialOffer: credentialOffer, issuerConfig: issuerMetadata, accessToken: tokenResponse.accessToken, format: "")
```

</TabItem>
</Tabs>

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:

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val credentialResponse = issueService.processDeferredCredentialRequest(acceptanceToken, issuerMetadata.issuerConfig?.deferredCredentialEndpoint)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let credentialResponse = await issueService?.processDeferredCredentialRequest(acceptanceToken: acceptanceToken, deferredCredentialEndPoint: issuerConfig.deferredCredentialEndpoint)
```

</TabItem>
</Tabs>

## Verifiable Presentation Functions

### Authorisation Request

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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val authorisationRequest = VerificationService().processAuthorisationRequest(data)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let authorisationRequest = await verificationHandler.processAuthorisationRequest(data: data)
```

```mdx-code-block
</TabItem>
</Tabs>
```

### 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

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val filteredCredentials = VerificationService().filterCredentials(<All credentials in the storage>, authorisationRequest)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let filteredCredentials = verificationHandler.filterCredentials(credentialList:<All stored credentials>, presentationDefinition: presentationDefinitionModel)
```

```mdx-code-block
</TabItem>
</Tabs>
```

#### Step 2: Send Authorisation Response

```mdx-code-block
<Tabs>
<TabItem value="Android">
```

```kotlin showLineNumbers title="MyActivity.kt"
val authorisationCode = VerificationService().sendVPToken(did, jwk, authorisationRequest, filteredCredentials)
```

```mdx-code-block
</TabItem>
```

```mdx-code-block
<TabItem value="iOS">
```

```swift showLineNumbers title="MyViewController.swift"
let authorisationCode = await verificationHandler.sendVPToken(did: did, secureKey: jwk.1, authorisationRequest: presentationRequest, credentialsList: [filteredCredentials])
```

```mdx-code-block
</TabItem>
</Tabs>
```
