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.mdYou do not need every part. A website needs web/ only; an in-person app needs android/ or ios/.
Requirements
Section titled “Requirements”| 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.
-
Copy the
.tgzinto your project (for examplevendor/) and install it. The version is in the file name, so a later update is a new file and a newnpm install.Terminal window npm install ./vendor/wallet-verify-0.7.0.tgz -
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" />} -
TypeScript users get the element type from the package:
import type { WalletVerifyElement, VerifyResult } from '@wallet/verify'
Continue with the website Quickstart.
Android (Android Studio)
Section titled “Android (Android Studio)”-
Put the SDK next to your project. Unzip
android/into your project folder asvendor/wallet-maven/. It is a normal Maven repository. -
Tell Gradle where it is. Open
settings.gradle.ktsand add the folder to the repositories:dependencyResolutionManagement {repositories {maven { url = uri("vendor/wallet-maven") } // the Wallet SDKgoogle()mavenCentral()}} -
Add the libraries. Open your app module’s
build.gradle.ktsand add:dependencies {implementation("com.wallet.sdk:sdk-core:0.7.0") // the SDK: wallet + verifierimplementation("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} -
Click Sync Now in the bar Android Studio shows at the top of the editor.
-
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.
iOS (Xcode)
Section titled “iOS (Xcode)”-
Add the framework. Drag
ios/Wallet.xcframeworkonto 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. -
Link SQLite. In the Build Settings tab, search for Other Linker Flags and add
-lsqlite3. -
Add the screens’ texts and icons. Drag
ios/compose-resourcesonto the project and choose Create folder references (it shows as a blue folder), with your app target ticked. -
Explain the camera and Bluetooth. In the Info tab, under Custom iOS Target Properties, add
NSCameraUsageDescriptionandNSBluetoothAlwaysUsageDescriptionwith a sentence each; the screens ask for both. AddCADisableMinimumFrameDurationOnPhone=YESfor smooth 120 Hz scrolling. -
Check it worked: add
import Walletto a Swift file and press ⌘B. The build succeeds, andWallet.sharedautocompletes.
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.
Updating
Section titled “Updating”- Web: install the new
.tgz; the version in the file name changes. - Android: replace the
vendor/wallet-mavenfolder and bump the version inbuild.gradle.kts. - iOS: replace
Wallet.xcframeworkandcompose-resources.
Keep all three on the same version when you use more than one; the trust lists and document types are shared.
Versions
Section titled “Versions”| 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 |
Licence and distribution
Section titled “Licence and distribution”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.Walletimport com.wallet.WalletSdkimport 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)Native configuration
Section titled “Native configuration”Wallet.create(SdkConfig)
Section titled “Wallet.create(SdkConfig)”| 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.
TrustConfig
Section titled “TrustConfig”| 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) |
Requests and presets
Section titled “Requests and presets”import com.wallet.model.DocTypesimport com.wallet.model.PresentationRequestimport com.wallet.model.PresetAnswerimport 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.
Document types
Section titled “Document types”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.
Holder API (sdk.wallet)
Section titled “Holder API (sdk.wallet)”credentials(), details(id), previewOffer(uri), issueFromOffer(uri), issueFromIssuer(configId),
startPresentment(credentialId?) → PresentmentSession (state, approve(fields), cancel()).
Verifier API (sdk.verifier)
Section titled “Verifier API (sdk.verifier)”startReaderSession(request) → VerificationSession (state, connect(qr), cancel());
verify(deviceResponse, sessionTranscript) → AcceptanceResult.
Screens (sdk-ui-compose)
Section titled “Screens (sdk-ui-compose)”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).
For AI tools (llms.txt)
Section titled “For AI tools (llms.txt)”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.
How to use them
Section titled “How to use them”- Paste the
llms-full.txtlink 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.