Data Wallet (UI) SDKs
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:
- Android
- iOS
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" }
}
dependencies {
implementation 'com.github.L3-iGrant:data_wallet:2026.8.1'
}
Additional dependencies:
dependencies {
implementation 'com.github.L3-iGrant:wallet-store:2026.8.1'
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:
configurations.all {
exclude group: 'org.slf4j', module: 'slf4j-api'
resolutionStrategy {
force 'org.slf4j:slf4j-api:2.0.9'
}
}
The SDK is in a private repository. Contact [email protected] for read access to L3-iGrant/data-wallet-sdk-ios, then sign that GitHub account in under Xcode > Settings > Accounts using a personal access token with the repo scope.
Install SDK using SPM. To install, do the following:
- In Xcode, select File > Add Package Dependencies...
- Enter the URL:
https://github.com/L3-iGrant/data-wallet-sdk-ios - Use the latest version shown in the dialog
- Add the
ama-ios-sdkproduct to your app target
Requires iOS 15 or later, and a physical device as the SDK uses App Attest.
Add the following keys to the app's Info.plist:
NSCameraUsageDescriptionfor QR scanning.NSFaceIDUsageDescriptionfor biometric confirmation. Without it, iOS terminates the app at the first biometric prompt.
Step 02: Initialise Data Wallet
- Android
- iOS
DataWallet.initializeSdk(
this,
object : InitializeWalletCallback {
override fun progressUpdate(progress: Int) {
when (progress) {
InitializeWalletState.INITIALIZE_WALLET_STARTED -> {}
InitializeWalletState.INITIALIZE_WALLET_EXTERNAL_FILES_LOADED -> {}
InitializeWalletState.WALLET_OPENED -> {
// Wallet is ready. Register a notification listener here if needed —
// see "Subscribe To Notifications" below.
}
}
}
},
viewMode = ViewMode.BottomSheet
)
Import the SDK into your code using the following import statement.
import ama_ios_sdk
final class WalletHost: AriesMobileAgentDelegate {
func notificationReceived(message: String) {
// Called by the SDK when a notification arrives
}
}
let delegate = WalletHost()
@MainActor
func configureWallet() {
AriesMobileAgent.shared.configureWallet(
delegate: delegate,
isAriesEnabled: false,
viewMode: .BottomSheet // or .FullScreen
) { success in
DispatchQueue.main.async {
if success == true {
// 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. The cases are capitalised, .BottomSheet and .FullScreen.
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.
- Android
- iOS
DataWallet.showWallet(this)
AriesMobileAgent.shared.showDataWalletHomeViewController(showBackButton: true)
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.
- Android
- iOS
DataWallet.showConnections(this)
AriesMobileAgent.shared.showDataWalletConnectionsViewController()
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.
- Android
- iOS
DataWallet.showNotifications(this)
AriesMobileAgent.shared.showDataWalletNofificationViewController()
Note the spelling Nofification in the shipped SDK. A corrected alias is planned.
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.
- Android
- iOS
DataWallet.showMySharedData(this)
AriesMobileAgent.shared.showDataWalletShareDataHistoryViewController()
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.
- Android
- iOS
DataAgreementUtils.fetchDataAgreement(
"api_key",
"organization_id",
"agreement_id",
this
)
AriesMobileAgent.shared.showDataAgreementScreen(
dataAgreementID: "agreement_id",
apiKey: "api_key",
orgId: "organization_id"
)
Delete Data Wallet
- Android
- iOS
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
}
}
}
AriesMobileAgent.shared.deleteWallet(completion: { success in
if success ?? false {
// Wallet deleted successfully
}
})
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.
- Android
- iOS
To register your app to open didcomm:// deeplinks, add the following:
<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.
if (intent.scheme == "didcomm"){
DataWallet.processDeepLink(this, intent.data.toString())
}
Register your URL scheme under CFBundleURLTypes, then forward the incoming URL to saveConnection(withPopup:url:).
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
Task {
let (success, _, message, _) =
await AriesMobileAgent.shared.saveConnection(
withPopup: true,
url: url.absoluteString
)
if !success {
print("Could not handle invitation: \(message ?? "unknown error")")
}
}
return true
}
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.
- Android
- iOS
DataWallet.changeLanguage(context, languageCode)
// Change the SDK language to English
AriesMobileAgent.shared.changeSDKLanguage(languageCode: "en")
Handle Notification
This function handles push notifications sent from the dashboard. It processes incoming issuance and verification requests as they arrive.
- Android
- iOS
DataWallet.handlePushNotification(message = Map<String, Any>)
The callbacks for this function are received through the registerForSubscription method.
func userNotificationCenter(
_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void
) {
let userInfo = response.notification.request.content.userInfo
AriesMobileAgent.shared.handlePushNotification(
data: userInfo,
otpHandler: { type, continueFlow in
DispatchQueue.main.async {
switch type {
case .PinEntryDuringIssuance:
// Prompt the user for a PIN, then continue
continueFlow()
case .Verification:
// Proceed with the verification flow
continueFlow()
}
}
}
)
completionHandler()
}
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.
- Android
- iOS
DataWallet.setNotificationListener(
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
}
}
)
Notifications are delivered through the delegate passed to configureWallet.
final class WalletHost: AriesMobileAgentDelegate {
func notificationReceived(message: String) {
// Called by the SDK when a notification arrives
}
}
Wallet Unit Attestation
This function turns on Wallet Unit Attestation and points the SDK at the attestation service.
- Android
- iOS
DataWallet.showWallet(
this,
enableWUA = true,
baseUrl = "https://your-attestation-service.example",
cloudProjectNumber = 1234567890L
)
baseUrl and cloudProjectNumber are both required when enableWUA is true. If either is missing, the wallet is not shown.
AriesMobileAgent.shared.enableWUA(baseURL: "https://your-attestation-service.example")
On iOS, call this before configureWallet. Both the flag and a non empty URL are required, so passing nil leaves the feature off.
Self Attested Credential
The SDKs provide applications with the ability to save, update, retrieve, and delete self-attested credentials securely.
Add
Allows the Applications can store self-attested credentials. When connectionID is not supplied, the connection name and location are required.
- Android
- iOS
val id = SelfAttestedOpenIDCredential().add(
title = "Title",
description = "Description",
attributes = mapOf(
"attribute1" to "value1",
"attribute2" to "Value2"
),
connectionName = "Connection name shown on the credential",
location = "Location shown on the credential",
vct = "credential_type",
logo = "https://example.org/logo.png"
)
let attributes = [["attribute1": "value1"], ["attribute2": "value2"]]
let credentialId = try await SelfAttestedOpenIDCredential.shared.add(
title: "Title",
description: "Description",
attributes: attributes,
connectionID: nil, // optional
connectionName: "Connection name shown on the credential",
connectionLocation: "Location shown on the credential",
issuedDate: Date(), // optional
vct: "credential_type",
logo: "https://example.org/logo.png"
)
Update
Allows the Applications can update self-attested credentials.
- Android
- iOS
SelfAttestedOpenIDCredential().update(
id = id,
title = "Title",
description = "Description",
attributes = mapOf(
"attribute1" to "value1",
"attribute2" to "Value2",
"attribute3" to "Value3" ),
)
try await SelfAttestedOpenIDCredential.shared.update(
title: "Title", // Updated title
description: "Description", // Updated description
attributes: attributes, // Updated key value pairs
credentialId: credentialId, // Id returned by add
connectionID: nil, // optional
connectionName: "Connection name", // optional
connectionLocation: "Location", // optional
vct: "credential_type" // optional
)
Get
Allows the Applications can read the self-attested credential.
- Android
- iOS
val credential = SelfAttestedOpenIDCredential().get(id)
await SelfAttestedOpenIDCredential.shared.get(id: credentialId) { title, description, attributes in
print("Title:", title)
print("Description:", description)
print("Attributes:", attributes)
}
Delete
Allows the Applications can delete the self-attested credential.
- Android
- iOS
SelfAttestedOpenIDCredential().delete(id)
SelfAttestedOpenIDCredential.shared.delete(id: credentialId) { success in
// success indicates whether the credential was removed
}
Backup and Restore
The SDKs enable 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.
Backup
To initiate the backup
- Android
- iOS
DataWallet.initiateBackUp(context)
AriesMobileAgent.shared.initiateBackup()
Restore
To initiate the restore the backup. Before restoring make sure to delete wallet.
- Android
- iOS
DataWallet.initiateRestore(context, object : RestoreCallback {
override fun onRestoreSuccess() {
// Handle successful restore here
}
override fun onRestoreFailed(error: String) {
// Handle restore failure here
}
})
AriesMobileAgent.shared.initiateRestore(viewMode: .BottomSheet) { success in
// success indicates whether the restore completed
}