Skip to content

Install & versions

The SDK is delivered as one zip file. One version number covers every platform, and every part in the zip was built and tested together.

wallet-sdk-0.7.0.zip
├── web/ wallet-verify-0.7.0.tgz the <wallet-verify> element (npm package @wallet/verify)
├── android/ a local Maven repository com.wallet.sdk:sdk-core, sdk-ui-compose, sdk-face
├── ios/ Wallet.xcframework, compose-resources/ the SDK and its ready-made screens (device + simulator)
│ └── face/ Wallet.xcframework + WalletFace.podspec the same, plus the face check (CocoaPods, iOS 16)
├── models/ facenet_512.tflite the face check's model, if you use it
├── docs/ this documentation as Markdown, plus llms.txt and llms-full.txt for AI tools
└── README.md

You do not need every part. A website needs web/ only; an in-person app needs android/ or ios/.

Platform Minimum Notes
Web any framework or plain HTML; Node.js 20+ to install the package the element is a standard web component; the verifier side is the Verify API, nothing to run
Android minSdk 26 (Android 8.0), JDK 17, Kotlin 2.2, Android Gradle Plugin 8.x Jetpack Compose for the ready-made screens; hardware-backed keys via Android Keystore
iOS iOS 15+, Xcode 16+ iOS 26 for the Digital Credentials provider extension; keys in the Secure Enclave

Bluetooth and camera permissions are requested by the ready-made screens when needed.

  1. Copy the .tgz into your project (for example vendor/) and install it. The version is in the file name, so a later update is a new file and a new npm install.

    Terminal window
    npm install ./vendor/wallet-verify-0.7.0.tgz
  2. Import the package once in browser code. Importing registers the <wallet-verify> element.

    import '@wallet/verify'

    In Next.js or any server-rendered framework, import it from a client component or inside useEffect, because it needs the DOM:

    'use client'
    import { useEffect } from 'react'
    export function VerifyStep() {
    useEffect(() => { import('@wallet/verify') }, [])
    return <wallet-verify endpoint="https://hakim-verify-api.vercel.app/v1/pk_live_yourkey" fields="Photo=portrait" />
    }
  3. TypeScript users get the element type from the package:

    import type { WalletVerifyElement, VerifyResult } from '@wallet/verify'

Continue with the website Quickstart.

  1. Put the SDK next to your project. Unzip android/ into your project folder as vendor/wallet-maven/. It is a normal Maven repository.

  2. Tell Gradle where it is. Open settings.gradle.kts and add the folder to the repositories:

    dependencyResolutionManagement {
    repositories {
    maven { url = uri("vendor/wallet-maven") } // the Wallet SDK
    google()
    mavenCentral()
    }
    }
  3. Add the libraries. Open your app module’s build.gradle.kts and add:

    dependencies {
    implementation("com.wallet.sdk:sdk-core:0.7.0") // the SDK: wallet + verifier
    implementation("com.wallet.sdk:sdk-ui-compose:0.7.0") // the ready-made screens (optional)
    implementation("androidx.activity:activity-compose:1.9.3")
    implementation("androidx.fragment:fragment-ktx:1.8.5") // the screens are hosted in a FragmentActivity
    }
  4. Click Sync Now in the bar Android Studio shows at the top of the editor.

  5. Check it worked: in any Kotlin file, type import com.wallet.Wallet. It resolves (no red text), and Build → Make Project succeeds.

Host the ready-made screens in a FragmentActivity rather than a plain ComponentActivity. The SDK’s libraries declare their own permissions (camera, Bluetooth), so you don’t need to change the manifest to verify in person. A wallet app also registers the link and credential-offer entry points described in Present.

  1. Add the framework. Drag ios/Wallet.xcframework onto your project in the navigator (tick Copy items if needed and your app target). Then select the target, open the General tab, and under Frameworks, Libraries, and Embedded Content set it to Embed & Sign.

  2. Link SQLite. In the Build Settings tab, search for Other Linker Flags and add -lsqlite3.

  3. Add the screens’ texts and icons. Drag ios/compose-resources onto the project and choose Create folder references (it shows as a blue folder), with your app target ticked.

  4. Explain the camera and Bluetooth. In the Info tab, under Custom iOS Target Properties, add NSCameraUsageDescription and NSBluetoothAlwaysUsageDescription with a sentence each; the screens ask for both. Add CADisableMinimumFrameDurationOnPhone = YES for smooth 120 Hz scrolling.

  5. Check it worked: add import Wallet to a Swift file and press ⌘B. The build succeeds, and Wallet.shared autocompletes.

The ready-made screens are UIViewControllers, such as WalletViewControllersKt.WalletViewController(sdk:) and WalletViewControllersKt.WalletVerifyViewController(sdk:presets:title:); in SwiftUI, wrap one in a UIViewControllerRepresentable (wallet Quickstart). A wallet app also adds a URL scheme and an Associated Domain for links from websites, and (iOS 26) an App Group with the Digital Credentials extension: see Present. For the face check, use ios/face/ instead of the plain framework: see Prove it’s you.

  • Web: install the new .tgz; the version in the file name changes.
  • Android: replace the vendor/wallet-maven folder and bump the version in build.gradle.kts.
  • iOS: replace Wallet.xcframework and compose-resources.

Keep all three on the same version when you use more than one; the trust lists and document types are shared.

Part Coordinates Current
Web @wallet/verify (wallet-verify-<ver>.tgz) 0.7.0
Android com.wallet.sdk:sdk-core, com.wallet.sdk:sdk-ui-compose, com.wallet.sdk:sdk-face (optional, face check) 0.7.0
iOS Wallet.xcframework (SDK + ready-made screens) with compose-resources/; ios/face/Wallet.xcframework + WalletFace.podspec (optional, face check; iOS 16, CocoaPods) 0.7.0
Model models/facenet_512.tflite (the face check’s model, shipped by your app) —
Verify API https://hakim-verify-api.vercel.app/v1 v1

The SDK is proprietary and distributed under your agreement; the zip is not published to a public package registry. Ask us for a new zip when you need an update, or see Support.

Everything lives in com.wallet.* (Kotlin) and is exported unchanged to Swift through the Wallet framework. Full signatures, generated from the source: API reference for Android (Kotlin) and iOS (Swift).

import com.wallet.Wallet
import com.wallet.WalletSdk
import com.wallet.config.* // SdkConfig, IssuerConfig, TrustConfig, ReaderIdentityConfig, …
import com.wallet.model.* // PresentationRequest, RequestPreset, CredentialType, DocTypes, …
import com.wallet.ui.* // WalletScreen, WalletVerifyScreen, WalletBranding (sdk-ui-compose)
Field Meaning
issuer: IssuerConfig baseUrl, clientId, redirectUri, dpopPolicy (ALLOW_BEARER_FALLBACK default, or REQUIRE_DPOP)
trust: TrustConfig see below
secureArea HARDWARE (Keystore / Secure Enclave, default) or SOFTWARE (emulators, tests)
iosAppGroupId iOS: App Group for storage shared with the Digital Credentials provider extension
readerIdentity: ReaderIdentityConfig? verifier role: privateKeyBase64 + certChainPem (leaf first) to sign requests
proximity: ProximityConfig offerCentralClientMode (Android wallets, default on)
credentialTypes: List<CredentialType> document types beyond the built-in driving licence
shareGuard: ShareGuard? wallet role: a check between the holder’s consent and signing, for the credential types it names; FaceShareGuard from sdk-face (Prove it’s you)

The result is a WalletSdk with .wallet (holder), .verifier (reader) and .capabilities. Create it once per process and share it.

Field Role Meaning
issuerRootsPem verifier issuer root certificates (IACA), PEM
issuerVical verifier a signed VICAL (issuer list with allowed document types)
issuerDisplayNames verifier names for issuer roots, shown when the document doesn’t disclose its authority
readerRootsPem wallet verifier root certificates, PEM
readerRical wallet a signed RICAL (reader list with names)
import com.wallet.model.DocTypes
import com.wallet.model.PresentationRequest
import com.wallet.model.PresetAnswer
import com.wallet.model.RequestPreset
PresentationRequest(docType, namespaces = mapOf("org.iso.23220.1" to setOf("portrait", "age_over_21")))
RequestPreset(id, section, title, subtitle, request, answer = PresetAnswer.Details, symbol = "ID")
PresetAnswer.Details | PresetAnswer.YesNo(element, label) | PresetAnswer.ValidUntil(element, label)

Built-in: DocTypes.MDL, DocTypes.PHOTO_ID, RequestPresets.mdl.

See the EmiratesIdType sample in the wallet Quickstart.

Kinds: Text, Date, DateTime, Picture, Boolean, Number, Sex. expiredBadge on a date shows a badge on the card once the date has passed.

credentials(), details(id), previewOffer(uri), issueFromOffer(uri), issueFromIssuer(configId), startPresentment(credentialId?) → PresentmentSession (state, approve(fields), cancel()).

startReaderSession(request) → VerificationSession (state, connect(qr), cancel()); verify(deviceResponse, sessionTranscript) → AcceptanceResult.

WalletScreen(sdk), WalletVerifyScreen(sdk, presets, title), WalletBranding.typography.

On iOS the same screens are UIViewControllers in the Wallet framework (Swift: WalletViewControllersKt.…):

Swift Shows
WalletViewController(sdk:) the whole wallet: cards, details, Scan, Present, offers, website requests
handleWalletUrl(url:sameDevice:) hands the wallet a link the app was opened with (offer or website request)
WalletPresentViewController(sdk:credentialId:onClose:) present in person on its own
WalletScanViewController(onScanned:onClose:) a QR scanner
CredentialOfferViewController(sdk:offerUri:onDone:) accept one credential offer
WalletVerifyViewController(sdk:presets:title:) the in-person verifier

Full signatures, generated from the source: API reference for Android (Kotlin) and iOS (Swift).

This site publishes its content in the llms.txt format, so a coding assistant can read the whole documentation in one go.

File Contents
/llms.txt an index: every page with its title, link and one-line description
/llms-full.txt every page in full, as Markdown, in one file
/llms-small.txt a shorter version for tools with a small context window

The same files are in the docs/ folder of the SDK zip, so they work offline and match the version you installed.

  • Paste the llms-full.txt link into your assistant, or add it to your project’s context (for example as a file in the repository your tool reads).
  • Ask questions such as “add the wallet-verify element to the identity step and read the result on the server” or “write the SdkConfig for an in-person verifier that trusts this VICAL”.
  • Every page is also readable as Markdown by appending nothing: the assistant fetches the same text a person reads.