---
id: data-wallet-sdks
title: Data Wallet (UI) SDKs
description: Integrate the Data Wallet UI SDKs for Android and iOS into your mobile application to enable secure credential storage and sharing.
keywords: [Data Wallet, UI SDK, Android SDK, iOS SDK, mobile wallet, verifiable credentials, EUDI Wallet, digital identity]
hide_title: false
sidebar_label: UI SDKs
slug: /data-wallet-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 Data Wallet (UI) 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 {
    google()
    mavenCentral()
    jcenter()
    maven {
            name = "GitHubPackages"
            url 'https://maven.pkg.github.com/L3-iGrant/ama-android-sdk'
            credentials {
                username = "L3-iGrant"
                password = <Contact to get password>
            }
        }
    maven { url 'https://igrant.io/java-packages'}
    maven { url "https://jitpack.io" }
}
```

```groovy showLineNumbers title="settings.gradle"
dependencies {
    implementation 'com.github.L3-iGrant:data_wallet:2025.10.2'
}
```

Additional dependencies:

```groovy showLineNumbers title="settings.gradle"
dependencies {
    implementation platform('com.google.firebase:firebase-bom:28.0.1')
    implementation 'com.google.firebase:firebase-dynamic-links-ktx'
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'com.google.android.material:material:1.3.0'
    implementation 'org.hyperledger:indy:1.16.0'
    implementation 'net.java.dev.jna:jna:5.6.0'
    implementation 'org.apache.commons:commons-lang3:3.7'
    implementation 'commons-io:commons-io:2.8.0'
    implementation('com.squareup.retrofit2:retrofit:2.7.1') {
        exclude module: 'okhttp'
    }
    implementation 'com.squareup.retrofit2:converter-gson:2.7.1'
    implementation 'com.squareup.okhttp3:okhttp:4.3.1'
    implementation 'com.squareup.okhttp3:logging-interceptor:4.3.1'
    implementation 'com.google.code.gson:gson:2.8.6'
    implementation 'com.github.bumptech.glide:glide:4.11.0'
    annotationProcessor 'com.github.bumptech.glide:compiler:4.11.0'
    implementation 'com.airbnb.android:lottie:3.5.0'
    implementation 'org.greenrobot:eventbus:3.1.1'
    annotationProcessor "org.greenrobot:eventbus-annotation-processor:3.1.1"
    implementation 'com.github.koushikcse:LoadingButton:1.7'
    implementation 'com.github.mediapark-pk:Base58-android:0.1'
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2'
    implementation 'com.tbuonomo:dotsindicator:4.2'
    implementation 'com.nimbusds:nimbus-jose-jwt:9.21'
    implementation 'androidx.preference:preference-ktx:1.2.0'
    implementation("com.github.decentralised-dataexchange:presentation-exchange-sdk-android:2024.11.1")
    implementation("co.nstant.in:cbor:0.9")
    implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.3"
    implementation 'org.jetbrains.kotlin:kotlin-reflect'
    implementation 'com.madgag.spongycastle:prov:1.58.0.0'
    implementation ("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.15.4")
    implementation ("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.4")
    implementation("com.fasterxml.woodstox:woodstox-core:7.1.0")
    implementation ("javax.xml.stream:stax-api:1.0-2")
    implementation ("com.hbb20:ccp:2.5.1")
    implementation("com.jayway.jsonpath:json-path:2.9.0")
    implementation 'com.github.decentralised-dataexchange:PassCodeText:2024.10.1'
    implementation "androidx.lifecycle:lifecycle-process:2.6.2"
    implementation 'com.github.decentralised-dataexchange:eudi-wallet-oid4vc-android:2025.10.1'
    implementation 'com.squareup.retrofit2:converter-scalars:2.9.0'
    implementation 'com.github.amoskorir:avatarimagegenerator:1.5.0'
}
```
If you encounter SLF4J version conflicts or `Duplicate class org.slf4j` errors during the build,
add the following configuration block to your **root-level** `build.gradle` file:

```gradle
configurations.all {
    exclude group: 'org.slf4j', module: 'slf4j-api'

    resolutionStrategy {
        force 'org.slf4j:slf4j-api:2.0.9'
    }
}
```
```mdx-code-block
</TabItem>
```

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

Install SDK using SPM. To install, do the following:

- In Xcode, select **File → Add Packages...**
- Enter the URL: `https://github.com/L3-iGrant/data-wallet-sdk-ios`

Add camera usage description: Go to the app's Info.plist, add the key NSCameraUsageDescription with an appropriate message.

</TabItem>
</Tabs>

## Step 02: Initialise Data Wallet

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.initializeSdk(
    this,
    object : InitializeWalletCallback {
        override fun progressUpdate(progress: Int) {
            when (progress) {
                InitializeWalletState.INITIALIZE_WALLET_STARTED -> {}
                InitializeWalletState.INITIALIZE_WALLET_EXTERNAL_FILES_LOADED -> {}
                InitializeWalletState.POOL_CREATED -> {}
                InitializeWalletState.WALLET_OPENED -> {
                    DataWalletConfigurations.registerForSubscription(this)
                }
            }
        }
    },
    LedgerNetworkType.getSelectedNetwork(this),
    isAriesEnabled = false,
    viewMode = ViewMode.BottomSheet
)
```

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

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

Import the SDK into your code using the following import statement.

```swift showLineNumbers title="MyViewController.swift"
import ama_ios_sdk
let delegate = // Set your delegate conforming to AriesMobileAgentDelegate
AriesMobileAgent.shared.configureWallet(
    delegate: delegate,
    isAriesEnabled: false,
    viewMode: .bottomSheet) { success in
        if let success = success, success {
            // Wallet configuration successful
        } else {
            // Wallet configuration failed
        }
    }
```
This function initialises and configures the Data Wallet. It takes a completion block as a parameter, which is called when the wallet configuration is completed. The success parameter indicates whether the wallet configuration was successful.

`ViewMode` defines how the wallet UI should appear, either as a bottom sheet or full screen.
</TabItem>
</Tabs>

## Supported Wallet Functions

### Show Wallet UI

This function presents the data wallet's home view. The wallet home provides a user interface for managing wallet contents, accessing shared data, and performing wallet-related operations.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.showWallet(this)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.showDataWalletHomeViewController(showBackButton: true)
```
</TabItem>
</Tabs>

### Show Connections UI

This function presents the connections view of the data wallet. This view displays the list of established connections, allowing users to manage their connections, view connection details, and perform connection-related actions.


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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.showConnections(this)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.showDataWalletConnectionsViewController()
```
</TabItem>
</Tabs>

### Show Notifications UI

This function presents the data wallet's notifications views. This view provides a user interface for managing wallet notifications, such as receiving and viewing notifications related to data sharing or wallet updates.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.showNotifications(this)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.showDataWalletNotificationViewController()
```

</TabItem>
</Tabs>

### Show MySharedData UI

This function presents the share data history view of the data wallet. The share data history view displays a log of all the shared data, allowing the user to view the details of each shared item and manage data-sharing permissions.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.showMySharedData(this)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.showDataWalletShareDataHistoryViewController()
```

</TabItem>
</Tabs>

### Show DataAgreementPolicy UI

This function enables your application, integrated with the wallet, to retrieve data agreements associated with a specific organisation. By passing the required parameters such as `api_key`, `organization_id`, and `agreement_id`, along with a context (`this`), the function securely fetches the details of the specified agreement. This capability is essential for managing data consents and agreements programmatically, ensuring that your application adheres to specified data use policies and user consents.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataAgreementUtils.fetchDataAgreement(
    "api_key",
    "organization_id",
    "agreement_id",
    this
)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.showDataAgreementScreen(
    dataAgreementID: "agreement_id",
    apiKey: "api_key",
    orgId: "organization_id"
)
```

</TabItem>
</Tabs>

### Delete Data Wallet

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.deleteWallet(this) { result ->
    when (result) {
        is DeleteWalletResult.Success -> {
            // Show success message or perform any other action
            DataWallet.releaseSdk()
        }
        is DeleteWalletResult.Error -> {
            // Show error message
        }
    }
}
```

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.deleteWallet(completion: { success in
     if success ?? false {
         // Wallet deleted successfully
     }
 })
```

</TabItem>
</Tabs>

### Query Credentials

This is used to query credentials based on the `credential definition ID` and `schema ID`. It will query all the credentials if we don't pass any value(s).

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.queryCredentials(
    "credential_definition_id",
    "schema_id"
)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
async {
  if let credentials =
    await AriesMobileAgent.shared.queryCredentials(
      credDefId: "cred_def_id",
      schemaId: "schema_id")
  {
  // Process the queried credentials
  }
}
```

</TabItem>
</Tabs>

### Process Deeplink

This function is used when scanning a QR code or generating a clickable link that opens the Data Wallet app, facilitating connections, as well as the issuance and verification of credentials. To integrate this functionality, add the specified intent filter to the activity where the SDK is initialised.

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

To register your app to open didcomm:// deeplinks, add the following:

```xml showLineNumbers title="AndroidManifest.xml"
<intent-filter>
 <action android:name="android.intent.action.VIEW" />
 <category android:name="android.intent.category.DEFAULT" />
 <category android:name="android.intent.category.BROWSABLE" />
 <data android:scheme="didcomm" />
</intent-filter>
```

Then, add the code below to Wallet SDK and initialise the callback -> InitializeWalletState.WALLET_OPENED.

```kotlin showLineNumbers title="MyActivity.kt"
if (intent.scheme == "didcomm"){
  DataWallet.processDeepLink(this, intent.data.toString())
}
```

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

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

```swift showLineNumbers title="MyViewController.swift"
Contact support@igrant.io
```

</TabItem>
</Tabs>

### Change Language

This function allows you to change the language used by the SDK. Provide the language code (e.g., "en" for English) to switch the SDK's localization to the desired language.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.changeLanguage(context, languageCode) 
```

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

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

```swift showLineNumbers title="MyViewController.swift"
// Change the SDK language to English
AriesMobileAgent.shared.changeSDKLanguage(languageCode: "en") 
```

</TabItem>
</Tabs>

### Connect Without a UI

This function enables your application, integrated with the wallet, to programmatically connect to another wallet, be it individual or organisational, without requiring a user interface for scanning or clicking a deep link. This feature can be particularly useful for automatically linking users to predefined organisations during app onboarding.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.saveConnection(
    Uri.parse("connection_invitation_url"),
    object : ConnectionCallback {
      override fun success(
          connectionId: String
      ) {}

      override fun failure(reason: String?) {}
    }
)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
Not Implemented
```

</TabItem>
</Tabs>

### Handle Notification

This function handles push notifications sent from the dashboard. It processes incoming issuance and verification requests as they arrive.

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.handlePushNotification(message =  Map<String, Any>)
```

The callbacks for this function are received through the `registerForSubscription` method.

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

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

```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.handlePushNotification(data: [String: Any]) { type, continueFlow in
    DispatchQueue.main.async {
        switch type {
        case .PinEntryDuringIssuance:
            // Prompt user for PIN, then continue
            continueFlow()
            
        case .Verification:
            // Proceed with verification flow
            continueFlow()
            
        default:
            break
        }
    }
}
```

</TabItem>
</Tabs>

### Subscribe To Notifications

This function enables your application, integrated with the wallet, to register for subscriptions using specific arguments such as `api_key` and `organization_id`. It sets up a listener to process incoming notifications by type, such as `SHARE_REQUEST`, `OFFER_REQUEST`, `REQUEST_WITH_PIN_ENTRY` or `VERIFY_REQUEST`. Upon notification receipt, it executes tailored logic and navigates to relevant screens based on the provided intent. This functionality is crucial for enabling dynamic, automatic responses to user interactions or system events. 

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

```kotlin showLineNumbers title="MyActivity.kt"
DataWalletConfigurations.registerForSubscription(this@MainActivity,
    object : NotificationListener {
        override fun receivedNotification(
            notificationType: String,
            intent: Intent
        ) {
            when (notificationType) {
                MessageTypes.SHARE_REQUEST -> {
                    // your logic
                    // intent will contain the screen to redirect
                    // startActivity(intent)
                }
                MessageTypes.OFFER_REQUEST -> {
                    // Do your logic
                    // intent will contain the screen to redirect
                    // startActivity(intent)
                }
                MessageTypes.REQUEST_WITH_PIN_ENTRY -> {
                   // startActivity(intent)
                }
                MessageTypes.VERIFY_REQUEST -> {
                   // startActivity(intent)
                }
            }
        }
        override fun walletReadyToUse() {
            //Get notified when wallet is ready to use
        }
        override fun pushNotificationResponse(status: Boolean) {
            // response to the handle push notification 
        }

    }
)
```

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

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

```swift showLineNumbers title="MyViewController.swift"
This is implemented in the handle notification function
```

</TabItem>
</Tabs>


### Self Attested Credential
The `ama-ios-sdk` provides applications with the ability to save, update, retrieve, and delete self-attested credentials securely. 
#### Add
Allows the Applications can store self-attested credentials.
```mdx-code-block
<Tabs>
<TabItem value="Android">
```
```kotlin showLineNumbers title="MyActivity.kt"
val id = SelfAttestedOpenIDCredential().add(
       title = "Title",
       description = "Description",
       attributes = mapOf(
           "attribute1" to "value1",
           "attribute2" to "Value2",
       ),
       vct = "credential_type,
       connectionName = <Connection name that should be visible in the credential>,
       location = <Location name that should be visible in the credential>,
       logo = " <logo url>"
   )
```
```mdx-code-block
</TabItem>
```
```mdx-code-block
<TabItem value="iOS">
```
```swift showLineNumbers title="MyViewController.swift"
var attritutes = [["Key": "Value"]]  
let credentialId = try await SelfAttestedOpenIDCredential.shared.add(
        title: String,
        description: String,
        attributes:  [[String: String]],
        connectionName: String,
        connectionLocation: String,
        vct: String,
        logo: String
)

```
</TabItem>
</Tabs>

#### Update
Allows the Applications can update self-attested credentials.
```mdx-code-block
<Tabs>
<TabItem value="Android">
```
```kotlin showLineNumbers title="MyActivity.kt"
SelfAttestedOpenIDCredential().update(
    id = id,
    title = "Title",
    description = "Description",
    attributes = mapOf(
        "attribute1" to "value1",
        "attribute2" to "Value2",
        "attribute3" to "Value3"       ),
)


```
```mdx-code-block
</TabItem>
```
```mdx-code-block
<TabItem value="iOS">
```
```swift showLineNumbers title="MyViewController.swift"
 try await SelfAttestedOpenIDCredential.shared.update(
        title: String,                     // Updated title
        description: String,               // Updated description
        attributes: [[String: String]],    // Updated key-value pairs
        credentialId: String,              // Wallet record ID of credential
        connectionName: String,            // (Optional if connectionID is provided)
        connectionLocation: String         // (Optional if connectionID is provided)
    )

```
</TabItem>
</Tabs>

#### Get
Allows the Applications can read the self-attested credential.
```mdx-code-block
<Tabs>
<TabItem value="Android">
```
```kotlin showLineNumbers title="MyActivity.kt"
val credential = SelfAttestedOpenIDCredential().get(id)
```
```mdx-code-block
</TabItem>
```
```mdx-code-block
<TabItem value="iOS">
```
```swift showLineNumbers title="MyViewController.swift"
await SelfAttestedOpenIDCredential.shared.get(id: String) { title, description, attributes in
    print("Title:", title)
    print("Description:", description)
    print("Attributes:", attributes)
}

```
</TabItem>
</Tabs>

#### Delete
Allows the Applications can delete the self-attested credential.
```mdx-code-block
<Tabs>
<TabItem value="Android">
```
```kotlin showLineNumbers title="MyActivity.kt"
SelfAttestedOpenIDCredential().delete(id)
```
```mdx-code-block
</TabItem>
```
```mdx-code-block
<TabItem value="iOS">
```
```swift showLineNumbers title="MyViewController.swift"
SelfAttestedOpenIDCredential.shared.delete(id: String) { success in
    
}
```
</TabItem>
</Tabs>

### Backup and Restore
The ama-ios-sdk enables applications to backup and restore wallet data.
Currently, backup and restore operations are supported only through Data Pods by igrant.io.

Before initiating backup or restore, users must have an account with [Data Pods](https://datapod.igrant.io/login).
#### Backup
To initiate the backup
```mdx-code-block
<Tabs>
<TabItem value="Android">
```
```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.initiateBackUp(context)
```
```mdx-code-block
</TabItem>
```
```mdx-code-block
<TabItem value="iOS">
```
```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.initiateBackup()
```
</TabItem>
</Tabs>

#### Restore
To initiate the restore the backup. Before restoring make sure to delete wallet.
```mdx-code-block
<Tabs>
<TabItem value="Android">
```
```kotlin showLineNumbers title="MyActivity.kt"
DataWallet.initiateRestore(context, object : RestoreCallback {
    override fun onRestoreSuccess() {
        // Handle successful restore here
    }

    override fun onRestoreFailed(error: String) {
        // Handle restore failure here
    }
})
```
```mdx-code-block
</TabItem>
```
```mdx-code-block
<TabItem value="iOS">
```
```swift showLineNumbers title="MyViewController.swift"
AriesMobileAgent.shared.initiateRestore() { success in
}
```
</TabItem>
</Tabs>
