Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ The iOS podspec URL is derived from the native SDK version this package pins (`d
[
"@didit-protocol/sdk-react-native",
{
"iosPodspecUrl": "https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.8.0/DiditSDK.podspec"
"iosPodspecUrl": "https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.9.0/DiditSDK.podspec"
}
]
```
Expand Down Expand Up @@ -200,7 +200,7 @@ didit_sdk_subspec = case $DiditSdkIosVariant
else
raise "Invalid $DiditSdkIosVariant '#{$DiditSdkIosVariant}'. Supported values: all, core, autodetection, nfc."
end
pod didit_sdk_subspec, :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.8.0/DiditSDK.podspec'
pod didit_sdk_subspec, :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.9.0/DiditSDK.podspec'
```

##### Swift Package Manager (optional)
Expand Down Expand Up @@ -322,6 +322,7 @@ import { startVerification } from '@didit-protocol/sdk-react-native';
// With startVerification — config is the second argument
const result = await startVerification('your-session-token', {
languageCode: 'es',
showLanguageSelector: true,
fontFamily: 'Avenir',
loggingEnabled: true,
showCloseButton: true,
Expand All @@ -334,6 +335,7 @@ const result = await startVerificationWithWorkflow('your-workflow-id', {
vendorData: 'user-123',
config: {
languageCode: 'es',
showLanguageSelector: true,
loggingEnabled: true,
showCloseButton: true,
showExitConfirmation: true,
Expand All @@ -346,6 +348,7 @@ const result = await startVerificationWithWorkflow('your-workflow-id', {
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `languageCode` | `string` | Device locale | ISO 639-1 language code (e.g. `"en"`, `"fr"`, `"ar"`) |
| `showLanguageSelector` | `boolean` | `false` | Show the web-style language selector on the welcome screen |
| `fontFamily` | `string` | System font | Custom font family name |
| `loggingEnabled` | `boolean` | `false` | Enable SDK debug logging |
| `showCloseButton` | `boolean` | `true` | Show close (X) button on verification step screens |
Expand All @@ -370,6 +373,14 @@ await startVerification(token, { languageCode: 'fr' });
await startVerification(token);
```

### `showLanguageSelector`

Set this to `true` to let users change the verification language from the welcome screen. The selector is hidden by default.

```tsx
await startVerification(token, { showLanguageSelector: true });
```

### `fontFamily`

Overrides the font used throughout the SDK UI. The font must be registered in your app's native configuration:
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ dependencies {
implementation "com.facebook.react:react-android"

// Didit native Android SDK
implementation "me.didit:$diditSdkAndroidArtifact:4.8.0"
implementation "me.didit:$diditSdkAndroidArtifact:4.9.0"

// Coroutines (required for state flow observation)
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ class SdkReactNativeModule(reactContext: ReactApplicationContext) :

return Configuration(
languageLocale = language,
showLanguageSelector = if (map.hasKey("showLanguageSelector")) map.getBoolean("showLanguageSelector") else false,
fontFamily = if (map.hasKey("fontFamily")) map.getString("fontFamily") else null,
loggingEnabled = if (map.hasKey("loggingEnabled")) map.getBoolean("loggingEnabled") else false,
showCloseButton = if (map.hasKey("showCloseButton")) map.getBoolean("showCloseButton") else true,
Expand Down
2 changes: 1 addition & 1 deletion example-expo/ios/Podfile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ target 'DiditExpoExample' do
else
raise "Invalid $DiditSdkIosVariant '#{$DiditSdkIosVariant}'. Supported values: all, core, autodetection, nfc."
end
pod didit_sdk_subspec, :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.8.0/DiditSDK.podspec'
pod didit_sdk_subspec, :podspec => 'https://raw.githubusercontent.com/didit-protocol/sdk-ios/4.9.0/DiditSDK.podspec'

use_expo_modules!

Expand Down
6 changes: 5 additions & 1 deletion ios/DiditSdkBridge.swift
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
/// Sendable value type that captures config primitives before crossing concurrency boundaries.
private struct ParsedConfig: Sendable {
let languageCode: String?
let showLanguageSelector: Bool
let fontFamily: String?
let loggingEnabled: Bool
let showCloseButton: Bool
Expand All @@ -203,6 +204,7 @@
init(_ dict: NSDictionary?) {
guard let dict = dict, dict.count > 0 else {
self.languageCode = nil
self.showLanguageSelector = false
self.fontFamily = nil
self.loggingEnabled = false
self.showCloseButton = true
Expand All @@ -216,6 +218,7 @@
return
}
self.languageCode = dict["languageCode"] as? String
self.showLanguageSelector = dict["showLanguageSelector"] as? Bool ?? false
self.fontFamily = dict["fontFamily"] as? String
self.loggingEnabled = dict["loggingEnabled"] as? Bool ?? false
self.showCloseButton = dict["showCloseButton"] as? Bool ?? true
Expand Down Expand Up @@ -244,7 +247,8 @@
defaultDocumentCamera: Self.parseCameraLens(defaultDocumentCamera) ?? .back,
defaultLivenessCamera: Self.parseCameraLens(defaultLivenessCamera) ?? .front,
showDocumentCameraSwitchButton: showDocumentCameraSwitchButton,
showLivenessCameraSwitchButton: showLivenessCameraSwitchButton
showLivenessCameraSwitchButton: showLivenessCameraSwitchButton,
showLanguageSelector: showLanguageSelector
)
}

Expand Down Expand Up @@ -312,7 +316,7 @@
}

private static func mapErrorType(_ error: VerificationError) -> String {
switch error {

Check warning on line 319 in ios/DiditSdkBridge.swift

View workflow job for this annotation

GitHub Actions / build-ios

switch must be exhaustive

Check warning on line 319 in ios/DiditSdkBridge.swift

View workflow job for this annotation

GitHub Actions / build-ios

switch must be exhaustive
case .sessionExpired:
return "sessionExpired"
case .networkError:
Expand Down Expand Up @@ -475,7 +479,7 @@
private static func travelRule(_ dict: [String: Any]) -> DiditTravelRuleInfo {
DiditTravelRuleInfo(
status: dict["status"] as? String,
`protocol`: dict["protocol"] as? String,

Check warning on line 482 in ios/DiditSdkBridge.swift

View workflow job for this annotation

GitHub Actions / build-ios

keyword 'protocol' does not need to be escaped in argument list

Check warning on line 482 in ios/DiditSdkBridge.swift

View workflow job for this annotation

GitHub Actions / build-ios

keyword 'protocol' does not need to be escaped in argument list
required: dict["required"] as? Bool,
obligationsCount: (dict["obligationsCount"] as? NSNumber)?.intValue,
originatorData: dict["originatorData"] as? [String: Any],
Expand Down Expand Up @@ -518,7 +522,7 @@
return
}
let message = transactionError.errorDescription ?? "Transaction request failed"
switch transactionError {

Check warning on line 525 in ios/DiditSdkBridge.swift

View workflow job for this annotation

GitHub Actions / build-ios

switch covers known cases, but 'DiditTransactionError' may have additional unknown values; this is an error in the Swift 6 language mode

Check warning on line 525 in ios/DiditSdkBridge.swift

View workflow job for this annotation

GitHub Actions / build-ios

switch covers known cases, but 'DiditTransactionError' may have additional unknown values; this is an error in the Swift 6 language mode
case .invalidToken:
reject("invalid_token", message, nil)
case .expiredToken:
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
{
"name": "@didit-protocol/sdk-react-native",
"version": "4.8.0",
"version": "4.9.0",
"diditNativeSdkVersions": {
"ios": "4.8.0",
"android": "4.8.0"
"ios": "4.9.0",
"android": "4.9.0"
},
"description": "React Native wrapper for Didit Identity Verification SDK",
"main": "./lib/commonjs/index.js",
Expand Down
6 changes: 6 additions & 0 deletions release-notes/4.9.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Adds the opt-in `showLanguageSelector` configuration option.

When enabled, users can change the verification language from the welcome screen using the same compact, searchable selector as the web verification flow.
The selector remains hidden by default.

Pins the iOS and Android native SDKs exactly to 4.9.0.
2 changes: 2 additions & 0 deletions src/NativeSdkReactNative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type EventEmitter<T> = CodegenTypes.EventEmitter<T>;
export type VerificationConfig = {
/** ISO 639-1 language code (e.g. "en", "fr", "ar"). Maps to SupportedLanguage on native. */
languageCode?: string;
/** Show the language selector on the welcome screen. Default: false. */
showLanguageSelector?: boolean;
/** Custom font family name. Must be registered by the host app. */
fontFamily?: string;
/** Enable SDK logging for debugging. Default: false. */
Expand Down
34 changes: 33 additions & 1 deletion src/__tests__/index.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import type { DiditTransactionResult } from '../types';
jest.mock('../NativeSdkReactNative', () => ({
__esModule: true,
default: {
startVerification: jest.fn(),
submitTransaction: jest.fn(),
getTransaction: jest.fn(),
onTransactionUpdated: jest.fn(() => ({ remove: jest.fn() })),
},
}));

import NativeSdkReactNative from '../NativeSdkReactNative';
import { submitTransaction, getTransaction } from '../index';
import { startVerification, submitTransaction, getTransaction } from '../index';

const mockStartVerification =
NativeSdkReactNative.startVerification as jest.Mock;
const mockSubmit = NativeSdkReactNative.submitTransaction as jest.Mock;
const mockGet = NativeSdkReactNative.getTransaction as jest.Mock;
const mockOnUpdated = NativeSdkReactNative.onTransactionUpdated as jest.Mock;
Expand Down Expand Up @@ -50,6 +53,35 @@ function pendingResult(
};
}

describe('verification configuration marshalling', () => {
beforeEach(() => {
mockStartVerification.mockReset();
mockStartVerification.mockResolvedValue({
type: 'completed',
sessionId: 'test-session',
status: 'Approved',
});
});

it('forwards an enabled language selector to native', async () => {
await startVerification('test-token', { showLanguageSelector: true });

expect(mockStartVerification).toHaveBeenCalledWith(
'test-token',
expect.objectContaining({ showLanguageSelector: true })
);
});

it('leaves the selector disabled when the option is omitted', async () => {
await startVerification('test-token', {});

expect(mockStartVerification).toHaveBeenCalledWith(
'test-token',
expect.objectContaining({ showLanguageSelector: undefined })
);
});
});

describe('transaction result marshalling', () => {
beforeEach(() => {
mockSubmit.mockReset();
Expand Down
2 changes: 2 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ export async function startVerification(
const nativeConfig = config
? {
languageCode: config.languageCode,
showLanguageSelector: config.showLanguageSelector,
fontFamily: config.fontFamily,
loggingEnabled: config.loggingEnabled,
showCloseButton: config.showCloseButton,
Expand Down Expand Up @@ -192,6 +193,7 @@ export async function startVerificationWithWorkflow(
const nativeConfig = options?.config
? {
languageCode: options.config.languageCode,
showLanguageSelector: options.config.showLanguageSelector,
fontFamily: options.config.fontFamily,
loggingEnabled: options.config.loggingEnabled,
showCloseButton: options.config.showCloseButton,
Expand Down
6 changes: 6 additions & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ export interface DiditConfig {
*/
languageCode?: string;

/**
* Show the language selector on the verification welcome screen.
* Default: `false`.
*/
showLanguageSelector?: boolean;

/**
* Custom font family name to use throughout the SDK UI.
* The font must be registered in your app's native configuration.
Expand Down
Loading