Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Nothing to remember. Nothing to steal. You are the key.
A description of, and links to, the Keyless sample apps to support integrators with a working example.
This pages explains how the Lockout Policy works, what the implications are for users and how it is set.
algRS256kid values.Keyless.showIntroductionScreen {
// Perform actions after user taps CTA
}//Keyless adds a td claim to the JWTs containing the data you specify
val jwtSigningInfo = JwtSigningInfo(claimTransactionData = "<your custom data")
// if you want to authenticate with biometric
val biomAuthConfig = BiomAuthConfig(jwtSigningInfo = jwtSigningInfo)
// if you want to authenticate with pin
val pinAuthConfig = PinAuthConfig(pin = "1234", jwtSigningInfo = jwtSigningInfo)
// perform the authentication
Keyless.authenticate(
configuration = biomAuthConfig, // pinAuthConfig if you use pin
onCompletion = { /*TODO: process result*/ }
)//Keyless adds a td claim to the JWTs containing the data you specify
let jwtSigningInfo = JwtSigningInfo(claimTransactionData: "<your custom data>")
// if you want to authenticate with biometric
let biomAuthConfig = BiomAuthConfig(jwtSigningInfo: jwtSigningInfo)
// if you want to authenticate with pin
let pinAuthConfig = PinAuthConfig(pin: "1234", jwtSigningInfo: jwtSigningInfo)
// perform the authentication
Keyless.authenticate(
configuration: biomAuthConfig, // pinAuthConfig if you use pin
onCompletion : { /*TODO: process result*/ }
) // Keyless adds a td claim to the JWTs containing the data you specify
const jwtSigningInfo = new JwtSigningInfo('<your custom data>');
// if you want to authenticate with biometric
const biomAuthConfig = new BiomAuthConfig({
jwtSigningInfo: jwtSigningInfo,
});
// if you want to authenticate with pin
const pinAuthConfig = new PinAuthConfig({
pin: '1234',
jwtSigningInfo: jwtSigningInfo,
});
const result = await Keyless.authenticate(
biomAuthConfig // or pinAuthConfig if you use pin
);
result.fold({
onSuccess(data) {
logConsole('Auth result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
},
});import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/jwt_signing_info.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
// Keyless adds a td claim to the JWTs containing the data you specify
final jwtSigningInfo = JwtSigningInfo("<your custom data>");
// if you want to authenticate with biometric
final biomAuthConfig = BiomAuthConfig(
jwtSigningInfo: jwtSigningInfo
);
// if you want to authenticate with pin
final pinAuthConfig = PinAuthConfig(
pin: "1234",
jwtSigningInfo: jwtSigningInfo
);
try {
// perform the authentication with either biometric or pin config
final result = await Keyless.instance.authenticate(
biomAuthConfig // or pinAuthConfig if you use pin
);
print("JWT signed successfully: ${result.signedJwt}");
} catch (error) {
print("Authentication failed: $error");
}lockoutDuration: Long, //seconds - default 300 seconds
lockoutAttemptsResetAfter: Long, //seconds - default 180 seconds
lockoutAttemptsThreshold: val configuration = BiomEnrollConfig()
Keyless.enroll(
let configuration = BiomEnrollConfig()
Keyless.enroll(
val configuration = EnrollmentConfiguration.builder.build()
Keyless.enroll(
enrollmentConfiguration = configuration,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "Enroll success - userId ${result.value.keylessId}")
is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "Enroll failure - error code ${result.error.code}")
}
}
)let configuration = Keyless.EnrollmentConfiguration.builder.build()
Keyless.enroll(
enrollmentConfiguration: configuration,
onCompletion: { result in
switch result {
case .success(let enrollmentSuccess):
print("Enrollment finished successfully. UserID: \(enrollmentSuccess.keylessId)")
case .failure(let error):
print("Enrollment finished with error: \(error.message)
}
})import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/enrollment_configuration.dart';
final configuration = BiomEnrollConfig();
try {
final result = await Keyless.instance.enroll(configuration);
print("Enrollment finished successfully. UserID: ${result.keylessId}");
} catch (error) {
print("Enrollment finished with error: $error");
}
import Keyless, { BiomEnrollConfig } from '@react-native-keyless/sdk';
const enrollUser = async () => {
const enroll = new BiomEnrollConfig();
const result = await Keyless.enroll(enroll);
result.fold({
onSuccess: (data) => {
console.log(`Enrollment finished successfully. UserID: ${data.keylessId}`);
},
onFailure: (error) => {
console.error('Enrollment finished with error:', error);
},
});
};Keyless.validateUserAndDeviceActive(
onCompletion = { result ->
when (result) {
Keyless.validateUserDeviceActive(
completionHandler: { error in
try {
await Keyless.validateUserAndDeviceActive();
print("user and device active");
} catch (error) {
print("user or device deactivated - error code: ${error.code}");
// error code 1131 = user is not enrolled on the device (not even locally so did not check on backend)
// error code 534 = user not found or deactivated on backend
// error code 535 = device not found or deactivated on backend
}import Keyless from '@react-native-keyless/sdk';
const validateUserAndDevice = async () => {
const result = await Keyless.validateUserAndDeviceActive();
result.fold({
onSuccess: () => {
console.log("user and device active");
},
onFailure: (error) => {
console.error(`user or device deactivated - error code: ${error.code}`);
// error code 1131 = user is not enrolled on the device (not even locally)
// error code 534 = user not found or deactivated on backend
// error code 535 = device not found or deactivated on backend
}
});
};public data class BiomEnrollConfig(
public val cameraDelaySeconds: Int = 2,
public val jwtSigningInfo: JwtSigningInfo?,
public val livenessConfiguration: LivenessSettings.LivenessConfiguration = LEVEL_1,
public val livenessEnvironmentAware: Boolean = true,
public val operationInfo: OperationInfo?,
public val shouldRetrieveEnrollmentFrame: Boolean = false,
public val showSuccessFeedback: Boolean = true,
public val showInstructionsScreen: Boolean = true,
public val showFailureFeedback: Boolean = true,
public val generatingClientState: ClientStateType? = null,
public val clientState: String? = null,
public val savingSecret: KeylessSecret? = null,
public val deletingSecret: KeylessSecret.Identifier? = null,
public val retrievingSecret: KeylessSecret.Identifier? = null,
public val shouldRetrieveSecretIDs: Boolean = false,
public val presentation: PresentationStyle = PresentationStyle.FULL_SCREEN
)public struct BiomEnrollConfig {
public let cameraDelaySeconds: Int
public let customSecret: String?
public let jwtSigningInfo: JwtSigningInfo?
public let livenessConfiguration: Keyless.LivenessConfiguration
public let livenessEnvironmentAware: Bool
public let operationInfo: Keyless.OperationInfo?
public let shouldReturnEnrollmentFrame: Bool
public let showSuccessFeedback: Bool,
public let showInstructionsScreen: Bool,
public let showFailureFeedback: Bool,
public let generatingClientState: ClientStateType?,
public let clientState: String?,
public let deletingSecret: KeylessSecret.Identifier?
public let retrievingSecret: KeylessSecret.Identifier?
public let shouldRetrieveSecretIDs: Bool
public let presentationStyle: PresentationStyle
}fun getUserId(): KeylessResult<String, KeylessSdkError>func getUserId() -> Result<String, KeylessSDKError>import Keyless from '@react-native-keyless/sdk';
const getUserId = async () => {
const result = await Keyless.getUserId();
result.fold({
onSuccess: (userId) => {
console.log("User ID:", userId);
},
onFailure: (error) => {
console.error("Failed to get user ID:", error);
},
});
};Future<String> getUserId() asyncval setup = SetupConfig(
apiKey = "...",
hosts = listOf(""),
keylessLogsConfiguration = LogsConfiguration(
enabled = true,
logLevel = LogLevels.INFO
),
customLogsConfiguration = LogsConfiguration(
enabled = true
)
)let configuration = SetupConfig(
apiKey: "some api key",
hosts: ["some.host"],
keylessLogsConfiguration: KeylessLogsConfiguration(enabled: true),
customLogsConfiguration: CustomLogsConfiguration(enabled: true, logLevel: .INFO, callback: { event in
print(event)
})
)
Keyless.configure(setupConfiguration: configuration) { error in
// handle error
}Keyless.customLogs.collect { logEvent ->
// handle the logEvent
}val setup = SetupConfig(
apiKey = "...",
hosts = listOf(""),
customLogsConfiguration = LogsConfiguration(
enabled = true,
logLevel = LogLevels.INFO // This is optional and defaults to INFO
)
)var myEventCollection = [LogEvent]()
let configuration = Keyless.SetupConfiguration
.builder
.withApiKey("some api key")
.withHosts(["some.host"])
.withLogging(
keylessLogsConfiguration: KeylessLogsConfiguration(enabled: true, logLevel: .INFO),
customLogsConfiguration: CustomLogsConfiguration(enabled: true, callback: { event in
myEventCollection.append(event)
})
)
.build()
Keyless.configure(setupConfiguration: configuration) { error in
// handle error
}
}public interface EnrollmentConfigurationBuilder {
public fun retrievingBackup(): EnrollmentConfigurationBuilder
public fun retrievingTemporaryState(): EnrollmentConfigurationBuilder
public fun savingSecret(customSecret: String): EnrollmentConfigurationBuilder
public fun withBackup(backupKey: ByteArray, backupData: ByteArray): EnrollmentConfigurationBuilder
public fun withDelay(cameraDelaySeconds: Int): EnrollmentConfigurationBuilder
public fun withEnrollmentSelfie(): EnrollmentConfigurationBuilder
public fun withLivenessSettings(
livenessConfiguration: LivenessSettings.LivenessConfiguration,
livenessTimeout: Int
): EnrollmentConfigurationBuilder
public fun withOperationInfo(
operationId: String,
payload: String? = null,
externalUserId: String? = null
): EnrollmentConfigurationBuilder
public fun withPin(pin: String): EnrollmentConfigurationBuilder
public fun withTemporaryState(temporaryState: String): EnrollmentConfigurationBuilder
public fun build(): EnrollmentConfiguration
}public protocol EnrollmentConfigurationBuilder {
public func retrievingBackup() -> EnrollmentConfigurationBuilder
public func retrievingTemporaryState() -> EnrollmentConfigurationBuilder
public func savingSecret(_ customSecret: String) -> EnrollmentConfigurationBuilder
public func withBackup(_ backup: Keyless.Backup) -> EnrollmentConfigurationBuilder
public func withDelay(seconds: Int) -> EnrollmentConfigurationBuilder
public func withEnrollmentSelfie() -> EnrollmentConfigurationBuilder
public func withLivenessSettings(
livenessConfiguration: Keyless.LivenessConfiguration,
livenessTimeout: Int
) -> EnrollmentConfigurationBuilder
public func withOperationInfo(
id: String,
payload: String?,
externalUserId: String?
) -> EnrollmentConfigurationBuilder
public func withPin(_ pin: String) -> EnrollmentConfigurationBuilder
public func withTemporaryState(_ temporaryState: String) -> EnrollmentConfigurationBuilder
public func build() -> Keyless.EnrollmentConfiguration
}class BiomEnrollConfig {
final String? customSecret;
final String? temporaryState;
final OperationInfo? operationInfo;
final LivenessConfiguration? livenessConfiguration;
final int? livenessTimeout;
final bool? shouldRetrieveTemporaryState;
final int? cameraDelaySeconds;
final JwtSigningInfo? jwtSigningInfo;
final DynamicLinkingInfo? dynamicLinkingInfo;
final bool? showScreenInstructions;
final bool? showScreenSuccessFlow;
}
// The BiomEnrollConfig can be instantiated with these optional properties.
// example: new BiomEnrollConfig({ customSecret: 'your-secret', cameraDelaySeconds: 3 });
class BiomEnrollConfig {
public readonly livenessConfiguration: LivenessConfiguration;
public readonly livenessEnvironmentAware: boolean;
public readonly cameraDelaySeconds: number;
public readonly generatingClientState: ClientStateType | null;
public readonly shouldRetrieveEnrollmentFrame: boolean;
public readonly clientState: string | null;
public readonly customSecret: string | null;
public readonly iamToken: string | null;
public readonly operationInfo: OperationInfo | null;
public readonly jwtSigningInfo: JwtSigningInfo | null;
public readonly showSuccessFeedback: boolean;
public readonly showFailureFeedback: boolean;
public readonly showScreenInstructions: boolean;
}
data class EnrollmentSuccess(
val keylessId: String,
val enrollmentFrame: Bitmap?,
val signedJwt: String?,
val clientState: String?,
val secret: KeylessSecret?,
val secretIDs: Set<KeylessSecret.Identifier>?
) : KeylessSdkSuccess()public struct EnrollmentSuccess {
public let keylessId: String?
public let enrollmentFrame: CGImage?
public let signedJwt: String?
public let clientState: String?
public let secret: KeylessSecret?
public let secretIDs: Set<KeylessSecret.Identifier>?
}class EnrollmentSuccess {
final String keylessId;
final String? customSecret;
final String? signedJwt;
final String? clientState;
}
class EnrollmentSuccess {
public readonly keylessId: string;
public readonly customSecret: string;
public readonly enrollmentFrame: string | null;
public readonly signedJwt: string | null;
public readonly clientState: string | null;
}
DEVELOPMENT
LEVEL_1 //recommended configuration
LEVEL_2fun getDevicePublicSigningKey(): KeylessResult<ByteArray, KeylessSdkError>func getDevicePublicSigningKey() -> Result<String, KeylessSDKError>Future<String> getDevicePublicSigningKey() asyncimport Keyless from '@react-native-keyless/sdk';
const getDevicePublicSigningKey = async () => {
const result = await Keyless.getDevicePublicSigningKey();
result.fold({
onSuccess: (key) => {
console.log("Device public key:", key);
},
onFailure: (error) => {
console.error("Failed to get device public key:", error);
},
});
};fun reset(
onCompletion: (KeylessResult<Unit, KeylessSdkError>) -> Unit
)func reset() -> KeylessSDKError?Future<void> reset() asyncimport Keyless from '@react-native-keyless/sdk';
const resetSdk = async () => {
const result = await Keyless.reset();
result.fold({
onSuccess: () => {
console.log("SDK reset successfully");
},
onFailure: (error) => {
console.error("SDK reset failed:", error);
},
});
};Keyless.getRateLimitInfo { result ->
when (result) {
is Keyless.KeylessResult.Success -> {
val rateLimitInfo = result.value
println("User is rate limited: ${rateLimitInfo.isRateLimited} with remaining seconds: ${rateLimitInfo.remainingSeconds}")
}
is Keyless.KeylessResult.Failure -> {
println("Error: ${result.error.message}")
}
}
}Keyless.getRateLimitInfo(completion: { result in
switch result {
case .success(let success):
print("User is rate limited: \(success.isRateLimited) with remaining seconds: \(success.remainingSeconds)")
case .failure(let error):
print("Error: \(error.message)")
}
})try {
final rateLimitInfo = await Keyless.instance.getRateLimitInfo();
print("User is rate limited: ${rateLimitInfo.isRateLimited} with remaining seconds: ${rateLimitInfo.remainingSeconds}");
} catch (error) {
print("Error: $error");
}import Keyless from '@react-native-keyless/sdk';
const getRateLimitInfo = async () => {
const result = await Keyless.getRateLimitInfo();
result.fold({
onSuccess: (info) => {
console.log(`User is rate limited: ${info.isRateLimited}, remaining seconds: ${info.remainingSeconds}`);
},
onFailure: (error) => {
console.error("Error fetching rate limit info:", error);
},
});
};val setupConfiguration = SetupConfiguration.builder
.withApiKey("")
.withHosts(listOf("..."))
.withLogging(
keylessLogsConfiguration = LogsConfiguration(enabled = true),
customLogsConfiguration = LogsConfiguration(enabled = true, logLevel = LogLevels.INFO)
)
.build()let configuration = Keyless.SetupConfiguration
.builder
.withApiKey("some api key")
.withHosts(["some.host"])
.withLogging(
keylessLogsConfiguration: KeylessLogsConfiguration(enabled: true, logLevel: .INFO),
customLogsConfiguration: CustomLogsConfiguration(enabled: true, callback: { event in
print(event)
})
)
.build()
Keyless.configure(setupConfiguration: configuration) { error in
// handle error
}final configuration = SetupConfiguration(
apiKey: apiKey,
hosts: [host],
loggingEnabled: true,
loggingLevel: LogLevel.info));
try {
final result = await Keyless.instance.configure(configuration);
print("Configure finished succcessfully.");
} catch (error) {
print("Configure finished with error: $error");
} const config = new SetupConfig({
apiKey: 'apiKey',
hosts: ['HOSTS'],
keylessLogsConfiguration: new LogsConfiguration({
enabled: true,
logLevel: LogLevels.INFO,
}),
customLogsConfiguration: new LogsConfiguration({
enabled: true,
logLevel: LogLevels.TRACE,
}),
});
const result = await Keyless.configure(config);
result.fold({
onSuccess: _data => {
//Handle success
},
onFailure: _error => {
//Handle error
},
const eventSubscription = Keyless.subscribeToCustomLogs(eventLog => {
// Handle log
});
const config = new SetupConfig({
apiKey: 'apiKey',
hosts: ['HOSTS'],
customLogsConfiguration: new LogsConfiguration({
enabled: true,
logLevel: LogLevels.TRACE,
}),
});
const result = await Keyless.configure(config);
result.fold({
onSuccess: _data => {
//Handle success
},
onFailure: _error => {
//Handle error
},
eventSubscription?.unsubscribe();repositoriessettings.gradleYOUR_CLOUDSMITH_TOKENdependencies {
// ...
implementation 'io.keyless:keyless-mobile-sdk:+'
}android {
// ...
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
// add the following only if you're using Kotlin
kotlinOptions {
jvmTarget = "1.8"
}
}swift package-registry set --global --scope keyless https://swift.cloudsmith.io/keyless/partners/
swift package-registry login https://swift.cloudsmith.io/keyless/partners/ --token <your-api-token>$ cd your-project-directory
$ pod initecho '${CLOUDSMITH_TOKEN}' | dart pub token add https://dart.cloudsmith.io/keyless/flutter/dart pub add keyless_flutter_sdk:PACKAGE_VERSION --hosted-url https://dart.cloudsmith.io/keyless/flutter/@react-native-keyless:registry=https://npm.cloudsmith.io/keyless/partners-rc/
//npm.cloudsmith.io/keyless/partners/:_authToken=YOUR_CLOUDSMITH_TOKEN# Using npm
npm install @react-native-keyless/sdk
# Using yarn
yarn add @react-native-keyless/sdk<application
...
android:name=".MainApplication"
...
</application>let setupConfig = SetupConfig(
apiKey: "KEYLESS_API_KEY",
hosts: ["KEYLESS_HOSTS"]
)
if let error = Keyless.configure(configuration: setupConfig) {
print("Keyless.Configure failed with error: \(error)")
}// MainApplication
override fun onCreate() {
super.onCreate()
// Initialize Keyless
Keyless.initialize(this)
}<application
...
android:name=".MainApplication"
...
</application>let setupConfiguration = Keyless.SetupConfiguration.builder
.withApiKey("KEYLESS_API_KEY")
.withHosts(["KEYLESS_HOSTS"])
.build()
if let error = Keyless.configure(configuration: setupConfiguration) {
print("Keyless.Configure failed with error: \(error)")
}import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/setup_configuration.dart';final setupConfiguration = SetupConfiguration(
apiKey: "KEYLESS_API_KEY",
hosts: ["KEYLESS_HOSTS"],
);
try {
await Keyless.instance.configure(setupConfiguration);
print("Keyless SDK configured successfully");
// Keyless is ready, you can now call
// enroll/authenticate/deEnroll ...
} catch (error) {
print("Failed to configure Keyless SDK: $error");
// Handle error
}// In MainApplication.kt
import io.reactnative.keyless.sdk.KeylessSDKModule // <-- Add this import
override fun onCreate() {
super.onCreate()
// Initialize Keyless
KeylessSDKModule.initialize(application = this)
// ... rest of your onCreate method
}# Keyless Proguard
-keep class io.keyless.sdk.** {*;}
-keepclassmembers class io.keyless.sdk.** {*;}// MainApplication
override fun onCreate() {
super.onCreate()
// Initialize Keyless
Keyless.initialize(this)
}public interface KLNetworkingModule {
public fun sendHTTPRequest(
baseUrl: String,
path: String,
method: String,
headers: Map<String, String>,
body: String
): KLHTTPResponse
public data class KLHTTPResponse(
val errorCode: Int,
val httpCode: Int,
val responseBody: String
)
}public protocol KLNetworkingModule {
func sendHTTPRequest (
host: String,
url : String,
method: String,
headers : [String: String],
body : String) -> KLHTTPResponse
}
public struct KLHTTPResponse {
var errorCode: Int
var httpCode: Int
var responseBody : String
public init(errorCode: Int, httpCode: Int, responseBody: String) {
self.errorCode = errorCode
self.httpCode = httpCode
self.responseBody = responseBody
}
}dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url "https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/maven/"
}
}
} // MainApplication
override fun onCreate() {
super.onCreate()
// Initialize Keyless
Keyless.initialize(this, "my.app.test")
}val configuration = Keyless.AuthenticationConfiguration()
Keyless.authenticate(
authenticationConfiguration = configuration,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> {
Log.d("IntegratorActivity ", "Authenticate success")
}
is Keyless.KeylessResult.Failure -> {
when (result.error) {
is KeylessUserError.FaceNotMatching -> Log.d("IntegratorActivity ", "Face not matching")
is KeylessUserError.MaskDetected -> Log.d("IntegratorActivity ", "Mask detected")
is KeylessUserError.Spoofing -> Log.d("IntegratorActivity ", "Spoofing detected")
is KeylessUserError.Timeout -> Log.d("IntegratorActivity ", "The operation timed out")
is KeylessUserError.UserCancelled -> Log.d("IntegratorActivity ", "The user cancelled the operation")
is KeylessUserError.NoNetworkConnection -> Log.d("IntegratorActivity ", "No network connection available")
is KeylessUserError.Lockout -> Log.d("IntegratorActivity ", "Your account is temporarily locked")
else -> {
Log.d("IntegratorActivity ", "Authenticate failure")
val errorCode = result.error.code
val errorMessage = result.error.message
val errorCause = result.error.cause?.printStackTrace()
// here you could display a generic error popup with the error code
}
}
}
}
}
)let configuration = Keyless.AuthenticationConfiguration.builder.build()
Keyless.authenticate(authenticationConfiguration: configuration) { result in
switch result {
case .success(let authenticationSuccess):
print("authenticationDidFinish: \(authenticationSuccess.token)")
case .failure(let error):
switch error.kind {
case .userError(let userError):
switch userError {
case .faceNotMatching:
print("Face not matching")
case .maskDetected:
print("Mask detected")
case .spoofing:
print("Spoofing detected")
case .timeout:
print("The operation timed out")
case .userCancelled:
print("The user cancelled the operation")
case .noNetworkConnection:
print("No network connection available")
case .lockout:
print("Your account is temporarily locked")
}
default:
let code = error.code
let message = error.message
// here you could display a generic error popup with the error code
}
}
}import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
final configuration = BiomAuthConfig();
try {
final result = await Keyless.instance.authenticate(configuration);
print("Authentication successful");
} catch (error) {
if (error is KeylessError) {
switch (error.errorType) {
case KeylessErrorType.user:
if (error.code == KeylessErrorCase.faceNotMatching.code) {
print("Face not matching");
} else if (error.code == KeylessErrorCase.maskDetected.code) {
print("Mask detected");
} else if (error.code == KeylessErrorCase.spoofing.code) {
print("Spoofing detected");
} else if (error.code == KeylessErrorCase.timeout.code) {
print("The operation timed out");
} else if (error.code == KeylessErrorCase.userCancelled.code) {
print("The user cancelled the operation");
} else if (error.code == KeylessErrorCase.noNetworkConnection.code) {
print("No network connection available");
} else if (error.code == KeylessErrorCase.deviceTampered.code) {
print("Device security check failed");
} else if (error.code == KeylessErrorCase.lockout.code) {
print("Your account is temporarily locked");
}
break;
default:
// Handle internal or integration errors
print("Authentication failed: ${error.message} (Code: ${error.code})");
// Here you could display a generic error popup with the error code
}
}
}Permitted background task scheduler identifiers// android/settings.gradle
pluginManagement {
plugins {
// ... other plugins
id "org.jetbrains.kotlin.android" version "2.2.0" apply false // ✅ Must be 2.2.0 or higher
}
}YOUR_CLOUDSMITH_TOKEN<key>NSCameraUsageDescription</key>
<string>This app uses the camera to scan face.</string>cd ios && pod install {
"authentication" : {
"swift.cloudsmith.io" : {
"loginAPIPath" : "/keyless/<repo>",
"type" : "token"
}
},
"registries" : {
"keyless" : {
"supportsAvailability" : false,
"url" : "https://swift.cloudsmith.io/keyless/<repo>/"
}
"version" : 1
}# This is the Keyless repository for partners
source 'https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/cocoapods/index.git'
target 'MyApp' do
use_frameworks!
# Add the Keyless pod
pod 'keyless-mobile-sdk'
endpost_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'NO'
end
end
end$ pod install
Analyzing dependencies
Cloning spec repo `cloudsmith-YOUR_CLOUDSMITH_TOKEN-keyless-partners-cocoapods-index` from `https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/cocoapods/index.git`flutter pub getallprojects {
repositories {
google()
mavenCentral()
maven {
setUrl("https://dl.cloudsmith.io/YOUR_CUSTOM_TOKEN/keyless/partners/maven/")
}
}
} allprojects {
repositories {
google()
mavenCentral()
maven {
setUrl("https://dl.cloudsmith.io/$cloudsmithToken/keyless/partners/maven/")
}
}
} <provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="io.keyless.fluttersdk.KeylessInitializer"
android:value="androidx.startup" />
</provider>source 'https://dl.cloudsmith.io/YOUR_CUSTOM_TOKEN/keyless/partners/cocoapods/index.git'source 'https://dl.cloudsmith.io/'+ ENV['cloudsmithToken'] +'/keyless/partners/cocoapods/index.git'<key>NSCameraUsageDescription</key>
<string>Keyless needs access to your camera to enroll and authenticate you. Keyless cannot be used without your camera. Please allow camera permissions.</string>
<key>NSMicrophoneUsageDescription</key>
<string>Keyless needs access to your camera to enroll and authenticate you. Keyless cannot be used without your camera. Please allow camera permissions.</string> allprojects {
repositories {
google()
mavenCentral()
maven {
url "https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/maven/"
}
}
}# Add the Keyless source at the top
source 'https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/cocoapods/index.git'
source 'https://cdn.cocoapods.org/'val setupConfig = SetupConfig(
apiKey = "KEYLESS_API_KEY",
hosts = listOf("KEYLESS_HOSTS")
)
Keyless.configure(setupConfig) { result ->
when (result) {
is Keyless.KeylessResult.Success -> {
Log.d("KeylessSDK", "configure success")
// Keyless is ready, you can now call
// enroll/authenticate/deEnroll ...
}
is Keyless.KeylessResult.Failure ->{
Log.d("KeylessSDK", "configure error")
// Inspect result.error for more info
}
}
}val setupConfiguration = SetupConfiguration.builder
.withApiKey("KEYLESS_API_KEY")
.withHosts(listOf("KEYLESS_HOSTS"))
.build()
Keyless.configure(setupConfiguration) { result ->
when (result) {
is Keyless.KeylessResult.Success -> {
Log.d("KeylessSDK", "configure success")
// Keyless is ready, you can now call
// enroll/authenticate/deEnroll ...
}
is Keyless.KeylessResult.Failure ->{
Log.d("KeylessSDK", "configure error")
// Inspect result.error for more info
}
}
} // In MainApplication.kt
import io.reactnative.keyless.sdk.KeylessSDKModule // <-- Add this import
override fun onCreate() {
super.onCreate()
// Initialize Keyless
KeylessSDKModule.initialize(application = this, namespace = "my.app.test")
// ... rest of your onCreate method
} import Keyless, { SetupConfig } from '@react-native-keyless/sdk';
const config = new SetupConfig({
// Make sure to store your keys securely
apiKey: 'KEYLESS_API_KEY',
hosts: ['KEYLESS_HOSTS'],
});
const result = await Keyless.configure(config);
result.fold({
onSuccess: data => {
console.log('Keyless SDK configured successfully:', data);
// Keyless is ready, you can now call other methods
},
onFailure: error => {
console.error('Failed to configure Keyless SDK:', error);
},
});<key>NSCameraUsageDescription</key>
<string>Keyless needs access to your camera to enroll and authenticate you. Keyless cannot be used without your camera. Please allow camera permissions.</string><key>NSCameraUsageDescription</key>
<key>
This API allows for backend-to-backend communication between your backend and the Keyless servers.
// android/build.gradle
buildscript {
ext {
// ... other variables
kotlinVersion = "2.2.0" // ✅ 1. Define version here (must be 2.2.0 or higher)
}
repositories {
google()
mavenCentral()
}
dependencies {
// ... other classpaths
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") // ✅ 2. The variable is used on this line
}
}This set of API calls allows you to fetch and manipulate Keyless enabled devices.
This set of API calls allows you to make operations on various Keyless users.
val configuration = BiomDeEnrollConfig()
Keyless.deEnroll(
deEnrollmentConfiguration = configuration,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "De-enroll success")
is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "De-enroll failure - error code ${result.error.code}")
}
}
)let configuration = BiomDeEnrollConfig()
.build()
Keyless.deEnroll(
deEnrollmentConfiguration: configuration,
onCompletion: { error in
if let error = error {
print("De-Enrollment finished with error: \(error.message)")
} else {
print("De-Enrollment finished with success")
}
}
}val configuration = DeEnrollmentConfiguration.builder.build()
Keyless.deEnroll(
deEnrollmentConfiguration = configuration,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "De-enroll success")
is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "De-enroll failure - error code ${result.error.code}")
}
}
)let configuration = Keyless.DeEnrollmentConfiguration.builder
.build()
Keyless.deEnroll(
deEnrollmentConfiguration: configuration,
onCompletion: { error in
if let error = error {
print("De-Enrollment finished with error: \(error.message)")
} else {
print("De-Enrollment finished with success")
}
}
}import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/deenrollment_configuration.dart';
// Biometric de-enrollment
final configuration = BiomDeEnrollConfig(
livenessConfiguration: LivenessConfiguration.passiveStandaloneHigh,
livenessTimeout: 60,
cameraDelaySeconds: 0
);
// Or PIN-based de-enrollment
final configuration = PinDeEnrollConfig(
pin: "1234"
);
try {
await Keyless.instance.deEnroll(configuration);
print("De-enrollment successful");
} catch (error) {
print("De-enrollment failed: $error");
}import Keyless, {
BiomDeEnrollConfig,
PinDeEnrollConfig,
LivenessConfiguration
} from '@react-native-keyless/sdk';
// Biometric de-enrollment
const biometricDeEnroll = async () => {
const config = new BiomDeEnrollConfig();
const result = await Keyless.deEnroll(config);
result.fold({
onSuccess: () => {
console.log('De-enrollment successful');
},
onFailure: (error) => {
console.error('De-enrollment failed:', error);
},
});
};
// PIN-based de-enrollment
const pinDeEnroll = async () => {
const config = new PinDeEnrollConfig('1234');
const result = await Keyless.deEnroll(config);
result.fold({
onSuccess: () => {
console.log('De-enrollment successful');
},
onFailure: (error) => {
console.error('De-enrollment failed:', error);
},
});
};DEVELOPMENT
LEVEL_1 //recommended configuration
LEVEL_2Get the customer public key in PEM format
The customer service api key
The public key in PEM format
PEM key representation of the customer public key
-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwJ1 -----END PUBLIC KEY-----Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Get all user authentications in the last 10 minutes. This can be optionally filtered by operation id in order to return a specific transaction/authentication attempt.
The customer service api key
The user id
Operation id to filter the results
User authentications
Current page number
Total number of elements
Total number of pages
Size of the page
An HEX string representing the user id
0123456789ABCDEFLocal date time representing when the authentication has been created
Error code representing the error that occurred during the authentication. 0 means no error
Unique operation identifier set and managed by the client
Authentication type of the operation
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
User not found
Get all user authentications in the last 10 minutes using the External User ID (i.e. the unique identifier the user is identified by in your own system). This can be optionally filtered by operation id in order to return a specific transaction/authentication attempt.
The customer service api key
The customer-meaningful user id. Case-sensitive
Operation id to filter the results
External user authentications
Current page number
Total number of elements
Total number of pages
Size of the page
User id set and managed by the client
Local date time representing when the authentication has been created
Error code representing the error that occurred during the authentication. 0 means no error
Unique operation identifier set and managed by the client
Authentication type of the operation
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
External user not found
Get user devices
The customer service api key
The user id
User devices
An HEX string representing the user id
0123456789ABCDEFCustomer unique identifier
Device public signing key
Device public encryption key
Device state
ACTIVEAlways set to '2'2020-01-02T03:04:05.242194378Device operation system version
Device's SDK version
Deletion date time
2020-01-02T03:04:05.242194378Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
An internal error occurred, please try again later or contact the support.
Delete user device
The customer service api key
The user id
Public signing key
Device successfully deleted
Positive feedback on the operation result
Always true
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
An internal error occurred, please try again later or contact the support.
Delete an user and all associated entities
The customer service api key
The user id
User successfully deleted
Positive feedback on the operation result
Always true
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
An internal error occurred, please try again later or contact the support.
Use a photo (from an identity document) to enroll the initial biometric data of the user
The user id
User id set and managed by the client
External user created
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
The requested operation conflicts with the current state of the server
Media type not supported, the request can't be processed
An internal error occurred, please try again later or contact the support.
The user id
User id set and managed by the client
External user patched
Customer identifier
An HEX string representing the user id
0123456789ABCDEFUser id set and managed by the client
Local date time representing when the resource has been created
2025-08-06T15:04:05.242194378Local date time representing when the resource has been modified the last time
2025-08-06T15:04:05.242194378Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Media type not supported, the request can't be processed
An internal error occurred, please try again later or contact the support.
The customer-meaningful user id. Case-sensitive
External user deleted. If the external user does not exist, the response is still positive
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
An internal error occurred, please try again later or contact the support.
No content
The customer service api key
The customer-meaningful user id. Case-sensitive
All users found bound to external user id. Empty if none is found
An HEX string representing the user id
0123456789ABCDEFDevice biometric public signing key
0123456789ABCDEFLocal date time representing when the resource has been created
2025-08-06T15:04:05.242194378Local date time representing when the resource has been modified the last time
2025-08-06T15:04:05.242194378Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
The requested operation conflicts with the current state of the server
An internal error occurred, please try again later or contact the support.
The user id
An user's pending operations
Unique operation identifier set and managed by the client
Operation payload set and managed by the client
User id set and managed by the client
Authentication type of the operation
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
An internal error occurred, please try again later or contact the support.
Unique operation identifier set and managed by the client
A customer operation
Unique operation identifier
Creation date time
2020-01-02T03:04:05.68Name of the service that created the operation
An HEX string representing the user id
0123456789ABCDEFCustomer SDK api key
User id set and managed by the client
Unique operation identifier set and managed by the client
Operation payload set and managed by the client
True if the operation is approved, false otherwise
Authentication type of the operation
State of the operation. Possible values are 'approved' or 'pending'
approvedRequest is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
An internal error occurred, please try again later or contact the support.
The user id
User id set and managed by the client
Unique operation identifier set and managed by the client
Operation payload set and managed by the client
Operation created successfully
Positive feedback on the operation result
Always true
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Resource not found
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
The requested operation conflicts with the current state of the server
Media type not supported, the request can't be processed
An internal error occurred, please try again later or contact the support.
The signed JWT message
The verification completed successfully. Check the result to see if the signature is valid or not
True if the signature is valid, false otherwise
Request is invalid and shouldn't be retried if the request is unchanged
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Unauthorized request, the request can't be processed unless you provide a valid authentication method
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Not acceptable representation
Problem detail response following the RFC 9457
A URI reference that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type. When this member is not present, its value is assumed to be "about:blank".
A short, human-readable summary of the problem type.
The HTTP status code generated by the origin server for this occurrence of the problem.
A human-readable explanation specific to this occurrence of the problem.
A URI reference that identifies the specific occurrence of the problem.
Media type not supported, the request can't be processed
// clientState retrieved from previous step
val clientState = "<your_client_state>"
val enrollConfig = BiomEnrollConfig(clientState = clientState)
Keyless.enroll(
configuration = enrollConfig,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> {
// account recovered
val userId = result.value.userId
}
is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
}
}
)
POST /v2/users/{userId}/external-user HTTP/1.1
X-Api-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 25
{
"externalUserId": "text"
}{
"sdkCustomerId": 1,
"userId": "0123456789ABCDEF",
"externalUserId": "text",
"createdAt": "2025-08-06T15:04:05.242194378",
"updatedAt": "2025-08-06T15:04:05.242194378"
}PATCH /v2/users/{userId}/external-user HTTP/1.1
X-Api-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 25
{
"externalUserId": "text"
}{
"sdkCustomerId": 1,
"userId": "0123456789ABCDEF",
"externalUserId": "text",
"createdAt": "2025-08-06T15:04:05.242194378",
"updatedAt": "2025-08-06T15:04:05.242194378"
}DELETE /v2/external-users/{externalUserId} HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
GET /v2/external-users/{externalUserId}/users HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
[
{
"userId": "0123456789ABCDEF",
"biometricPublicSigningKey": "0123456789ABCDEF",
"createdAt": "2025-08-06T15:04:05.242194378",
"updatedAt": "2025-08-06T15:04:05.242194378"
}
]GET /v2/users/{userId}/operations/pending HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
[
{
"operationId": "123456abcdef",
"operationPayload": "payload",
"externalUserId": "abcdef123456",
"authType": "biom"
},
{
"operationId": "654321fedcba"
}
]GET /v2/operations/{operationId} HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
{
"id": 1,
"timestamp": "2020-01-02T03:04:05.68",
"nodeId": "text",
"userId": "0123456789ABCDEF",
"apiKey": "text",
"externalUserId": "text",
"operationId": "text",
"operationPayload": "text",
"result": true,
"authType": "biom",
"state": "approved"
}POST /v2/users/{userId}/operations HTTP/1.1
X-Api-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 72
{
"externalUserId": "text",
"operationId": "text",
"operationPayload": "text"
}{
"success": true
}GET /v2/verify-jwt/public-key HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
{
"content": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwJ1\n-----END PUBLIC KEY-----"
}POST /v2/verify-jwt HTTP/1.1
X-Api-Key: YOUR_API_KEY
Content-Type: application/json
Accept: */*
Content-Length: 18
{
"message": "text"
}{
"result": true
}
// clientState retrieved from previous step
let clientState = "<your_client_state>"
let enrollConfig = BiomEnrollConfig(clientState: clientState)
Keyless.enroll(
configuration: enrollConfig,
onCompletion: { result in
switch result {
case .success(let enrollSuccess):
// account recovered
let userId = enrollSuccess.userId
case .failure(let error):
print("error code: \(error.code)
}
})import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/enrollment_configuration.dart';
// temporaryState retrieved from previous step
final temporaryState = "<your_temporary_state>";
final enrollConfig = BiomEnrollConfig(temporaryState: temporaryState);
try {
final result = await Keyless.instance.enroll(enrollConfig);
// account recovered
print("Account recovered successfully. UserID: ${result.keylessId}");
} catch (error) {
print("Account recovery failed: $error");
}const clientState = '<your client state';
const config = new BiomEnrollConfig({
clientState: clientState,
});
const result = await Keyless.enroll(config);
result.fold({
onSuccess(data) {
logConsole('Enroll result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
},
});GET /v2/users/{userId}/authentications HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
{
"page": {
"number": 1,
"totalElements": 1,
"totalPages": 1,
"size": 1
},
"content": [
{
"userId": "0123456789ABCDEF",
"authentications": [
{
"createdAt": "text",
"result": "APPROVED",
"errorCode": 1,
"operationId": "text",
"deviceId": "text",
"authType": "biom"
}
]
}
]
}GET /v2/external-users/{externalUserId}/authentications HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
{
"page": {
"number": 1,
"totalElements": 1,
"totalPages": 1,
"size": 1
},
"content": [
{
"externalUserId": "text",
"authentications": [
{
"createdAt": "text",
"result": "APPROVED",
"errorCode": 1,
"operationId": "text",
"deviceId": "text",
"authType": "biom"
}
]
}
]
}GET /v2/users/{userId}/devices HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
[
{
"userId": "0123456789ABCDEF",
"sdkCustomerId": 1,
"publicSigningKey": "text",
"publicEncryptionKey": "text",
"state": "ACTIVE",
"createdAt": "2020-01-02T03:04:05.242194378",
"osVersion": "text",
"sdkVersion": "text",
"deletedAt": "2020-01-02T03:04:05.242194378"
}
]DELETE /v2/users/{userId}/devices/{publicSigningKey} HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
{
"success": true
}DELETE /v2/users/{userId} HTTP/1.1
X-Api-Key: YOUR_API_KEY
Accept: */*
{
"success": true
}// ONLY FOR TEST
// Authentication Configuration
val authConfig = BiomAuthConfig
// ONLY FOR TEST
// Authentication Configuration
let authConfig = BiomAuthConfig(
livenessConfiguration: Keyless.LivenessConfiguration.DEVELOPMENT
livenessEnvironmentAware: false
)
// Enrollment Configuration
let enrollConfig = BiomEnrollConfig(
livenessConfiguration: Keyless.LivenessConfiguration.DEVELOPMENT
livenessEnvironmentAware: false
)
// De-Enrollment Configuration
let deEnrollConfig = BiomDeEnrollConfig(
livenessConfiguration: Keyless.LivenessConfiguration.DEVELOPMENT
livenessEnvironmentAware: false
)// ONLY FOR TEST
// Authentication Configuration
final authConfig = BiomAuthConfig(
livenessConfiguration: LivenessConfiguration.PASSIVE_STANDALONE_MEDIUM
// livenessEnvironmentAware: false - not available yet
);
// Enrollment Configuration
final enrollConfig = BiomEnrollConfig(
livenessConfiguration: LivenessConfiguration.PASSIVE_STANDALONE_MEDIUM
// livenessEnvironmentAware: false - not available yet
);
// De-Enrollment Configuration
final deEnrollConfig = BiomDeEnrollConfig(
livenessConfiguration: LivenessConfiguration.PASSIVE_STANDALONE_MEDIUM
// livenessEnvironmentAware: false - not available yet
);// ONLY FOR TEST
// Authentication Configuration
const authConfig = new BiomAuthConfig({
livenessConfiguration: LivenessConfiguration.PASSIVE_STANDALONE_MEDIUM,
livenessEnvironmentAware: false,
});
// Enrollment Configuration
const enrollConfig = new BiomEnrollConfig({
livenessConfiguration: LivenessConfiguration.PASSIVE_STANDALONE_MEDIUM,
livenessEnvironmentAware: false,
});
// De-Enrollment Configuration
const deEnrollConfig = new BiomDeEnrollConfig({
livenessConfiguration: LivenessConfiguration.PASSIVE_STANDALONE_MEDIUM,
livenessEnvironmentAware: false,
});
// photoBitmap is the bitmap you created from the document photo.
val configuration = PhotoEnrollConfig(photo = photoBitmap)
// photoUIImage is the UIImage you created from the document photo.
let configuration = PhotoEnrollConfig(photo:
import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/enrollment_configuration.dart';
// documentImage from eDocument.
final configuration = PhotoEnrollConfig(documentImage: documentImage);
try {
final result = await Keyless.instance.enroll(configuration);
print("Enrollment finished successfully. UserID: ${result.keylessId}");
} catch (error) {
print("Enrollment finished with error: $error");
}const config = new PhotoEnrollConfig({
photoBase64: '<photoBase64>',
});
const result = await Keyless.enroll(config);
result.fold({
onSuccess(data) {
logConsole('Enroll result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
},
});public data class PhotoEnrollConfig(
public val photo: Bitmap,
public val temporaryState: String? = null,
public val operationInfo: OperationInfo? = null,
public val jwtSigningInfo: JwtSigningInfo? = null
)public struct PhotoEnrollConfig{
public let photo: CGImage
public let operationInfo: Keyless.OperationInfo?
public let jwtSigningInfo: JwtSigningInfo?
public let temporaryState: String?
}class PhotoEnrollConfig{
final Uint8List? documentImage;
final String? temporaryState;
final OperationInfo? operationInfo;
final JwtSigningInfo? jwtSigningInfo;
}
class PhotoEnrollConfig {
public readonly photoBase64: string;
public readonly operationInfo: OperationInfo | null;
public readonly jwtSigningInfo: JwtSigningInfo | null;
public readonly clientState: string | null;
data class EnrollmentSuccess(
val signedJwt: String? = null,
) : KeylessSdkSuccess()public struct EnrollmentSuccess {
public let signedJwt: String?
}class EnrollmentSuccess {
final String? signedJwt;
} class EnrollmentSuccess {
public readonly keylessId: string;
public readonly customSecret: string;
public readonly enrollmentFrame: string | null;
public readonly signedJwt: string | null;
public readonly clientState: string | null;
}val enrollConfig = BiomEnrollConfig(generatingClientState = ClientStateType.BACKUP)
Keyless.enroll
val authConfig = BiomAuthConfig(generatingClientState = ClientStateType.BACKUP)
Keyless.authenticate
let enrollConfig = BiomEnrollConfig(generatingClientState: .backup)
Keyless.enroll(
configuration: enrollConfig,
onCompletion: { result in
switch result {
case .success(let enrollSuccess):
let clientState = enrollSuccess.clientState
// store the client state on your backend to recover the account in the future
case .failure(let error):
print("error code: \(error.code)
}
})let authConfig = BiomAuthConfig(generatingClientState: .backup)
Keyless.authenticate(
configuration: authConfig,
onCompletion: { result in
switch result {
case .success(let authSuccess):
let clientState = authSuccess.clientState
// store the client state on your backend to recover the account in the future
case .failure(let error):
print("error code: \(error.code)
}
})import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/enrollment_configuration.dart';
final enrollConfig = BiomEnrollConfig(shouldRetrieveTemporaryState: true);
try {
final result = await Keyless.instance.enroll(enrollConfig);
if (result.temporaryState != null) {
// store the temporary state on your backend to recover the account in the future
print("Temporary state retrieved: ${result.temporaryState}");
}
} catch (error) {
print("Enrollment failed: $error");
}import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
final authConfig = BiomAuthConfig(shouldRetrieveTemporaryState: true);
try {
final result = await Keyless.instance.authenticate(authConfig);
if (result.temporaryState != null) {
// store the temporary state on your backend to recover the account in the future
print("Temporary state retrieved: ${result.temporaryState}");
}
} catch (error) {
print("Authentication failed: $error");
}const config = new BiomEnrollConfig({
generatingClientState: ClientStateType.BACKUP,
});
const result = await Keyless.enroll(config);
result.fold({
onSuccess(data) {
logConsole('Enroll result success ' + JSON.stringify(data, null, 2));
const clientState = data.clientState;
// store the client state on your backend to recover the account in the future
logConsole('Client state ' + JSON.stringify(clientState, null, 2));
},
onFailure(error) {
logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
},
});"{\"artifact\":{\"family\":\"davideface_lite\",\"version\":\"1.2.0\",\"target\":\"mobile_sdk\",\"liveness\":\"liveness\"},\"core-client-state\":\"BASE_64_STATE\"}"[
{key1 : value1},
{key2 : value2},
...
{keyN: valueN}
]//Keyless adds a td claim to the JWTs containing the data you specify
val dynamicLinkingInfo = DynamicLinkingInfo(transactionData = "<your transaction data to display and sign>")
// authenticate with biometric
val biomAuthConfig = BiomAuthConfig(dynamicLinkingInfo = dynamicLinkingInfo)
// perform the authentication
Keyless.authenticate(
configuration = biomAuthConfig,
onCompletion = { /*TODO: process result*/ }
)//Keyless adds a td claim to the JWTs containing the data you specify
let dynamicLinkingInfo = DynamicLinkingInfo(transactionData = "<your transaction data to display and sign>")
// authenticate with biometric
let biomAuthConfig = BiomAuthConfig(dynamicLinkingInfo: dynamicLinkingInfo)
// perform the authentication
Keyless.authenticate(
configuration: biomAuthConfig,
onCompletion: { /*TODO: process result*/ }
)import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
import 'package:keyless_flutter_sdk/models/dynamic_linking_info.dart';
final dynamicLinkingInfo = DynamicLinkingInfo(transactionData: "<your transaction data to display and sign>");
// authenticate with biometric
final biomAuthConfig = BiomAuthConfig(dynamicLinkingInfo: dynamicLinkingInfo);
try {
// perform the authentication
final result = await Keyless.instance.authenticate(biomAuthConfig);
// process the signed JWT from result.signedJwt
print("Authentication successful. Signed JWT: ${result.signedJwt}");
} catch (error) {
print("Authentication failed: $error");
}// JWT header
{
"alg": "ES256",
"typ": "JWT",
"kid": "PIN/FACE"
}
// JWT payload
{
"iat": 1720519812,
"td": "your transaction data to display and sign",
"version": "1.1.0",
"sub": "keyless_id",
"external_user_id": "external user id only if present"
}public class KeylessSecret(
public val id: Identifier, // Unique identifier for the secret
public val value: Value // The actual secret content
)public struct KeylessSecret {
public let id: Identifier // Unique identifier for the secret
public let value: Value // The actual secret content
}const config = new BiomAuthConfig({
generatingClientState: ClientStateType.BACKUP,
});
const result = await Keyless.authenticate(config);
result.fold({
onSuccess(data) {
logConsole('Authenticate result success ' + JSON.stringify(data, null, 2));
const clientState = data.clientState;
// store the client state on your backend to recover the account in the future
logConsole('Client state ' + JSON.stringify(clientState, null, 2));
},
onFailure(error) {
logConsole('Authenticate result failure ' + JSON.stringify(error, null, 2));
},
});val configuration = BiomEnrollConfig(
savingSecret = KeylessSecret.of(
id = "your-secret-id",
value = "your-secret-value"
)
)
Keyless.enroll(configuration = configuration) { keylessResult ->
// Handle the result
}let configuration = BiomEnrollConfig(
savingSecret: KeylessSecret(
id: "your-secret-id",
value: "your-secret-value"
)
)
Keyless.enroll(
configuration: configuration,
onCompletion: { result in
switch result {
case .success(let success):
print("Secret saved successfully")
case .failure(let error):
print("Error: \(error.message)")
}
})val configuration = BiomAuthConfig(
retrievingSecret = KeylessSecret.Identifier("your-secret-id")
)
Keyless.authenticate(configuration = configuration) { keylessResult ->
if (keylessResult is KeylessResult.Success) {
val secret = keylessResult.value.secret
}
}let configuration = BiomAuthConfig(
retrievingSecret: "your-secret-id"
)
Keyless.authenticate(
configuration: configuration,
onCompletion: { result in
switch result {
case .success(let success):
if let secret = success.secret {
print("Secret ID: \(secret.id)")
print("Secret Value: \(secret.value)")
}
case .failure(let error):
print("Error: \(error.message)")
}
})val configuration = BiomAuthConfig(
deletingSecret = KeylessSecret.Identifier("your-secret-id")
)
Keyless.authenticate(configuration = configuration) { keylessResult ->
// Handle the result
}let configuration = BiomAuthConfig(
deletingSecret: "your-secret-id"
)
Keyless.authenticate(
configuration: configuration,
onCompletion: { result in
switch result {
case .success:
print("Secret deleted successfully")
case .failure(let error):
print("Error: \(error.message)")
}
})val configuration = BiomAuthConfig(shouldRetrieveSecretIDs = true)
Keyless.authenticate(configuration = configuration) { keylessResult ->
if (keylessResult is KeylessResult.Success) {
val secretIDs = keylessResult.value.secretIDs
}
}let configuration = BiomAuthConfig(shouldRetrieveSecretIDs: true)
Keyless.authenticate(
configuration: configuration,
onCompletion: { result in
switch result {
case .success(let success):
if let secretIDs = success.secretIDs {
for id in secretIDs {
print("Secret ID: \(id)")
}
}
case .failure(let error):
print("Error: \(error.message)")
}
})val configuration = BiomAuthConfig(
savingSecret = KeylessSecret.of(
id = "new-secret-id",
value = "new-secret-value"
),
retrievingSecret = KeylessSecret.Identifier("existing-secret-id"),
shouldRetrieveSecretIDs = true
)
Keyless.authenticate(configuration = configuration) { keylessResult ->
if (keylessResult is KeylessResult.Success) {
val retrievedSecret = keylessResult.value.secret
val allSecretIDs = keylessResult.value.secretIDs
}
}let configuration = BiomAuthConfig(
savingSecret: KeylessSecret(
id: "new-secret-id",
value: "new-secret-value"
),
retrievingSecret: "existing-secret-id",
shouldRetrieveSecretIDs: true
)
Keyless.authenticate(
configuration: configuration,
onCompletion: { result in
switch result {
case .success(let success):
if let secret = success.secret {
print("Retrieved secret: \(secret.value)")
}
if let secretIDs = success.secretIDs {
print("All secret IDs: \(secretIDs)")
}
case .failure(let error):
print("Error: \(error.message)")
}
})public data class BiomAuthConfig(
public val
public struct BiomAuthConfig: AuthConfig {
public
interface AuthenticationConfigurationBuilder {
fun retrievingBackup(): AuthenticationConfigurationBuilder
fun retrievingSecret(): AuthenticationConfigurationBuilder
fun deletingSecret(): AuthenticationConfigurationBuilder
fun retrievingTemporaryState(): AuthenticationConfigurationBuilder
fun withDelay(cameraDelaySeconds: Int): AuthenticationConfigurationBuilder
fun withLivenessSettings(
livenessConfiguration: LivenessSettings.LivenessConfiguration,
livenessTimeout: Int
): AuthenticationConfigurationBuilder
fun withMessageToSign(message: String): AuthenticationConfigurationBuilder
fun withOperationInfo(
operationId: String,
payload: String? = null,
externalUserId: String? = null
): AuthenticationConfigurationBuilder
fun withPin(pin: String): AuthenticationConfigurationBuilder
fun withSuccessAnimation(enabled: Boolean = true): AuthenticationConfigurationBuilder
fun build(): AuthenticationConfiguration
}public class Builder {
public func retrievingBackup() -> Builder
public func retrievingSecret() -> Builder
public func deletingSecret() -> Builder
public func retrievingTemporaryState() -> Builder
public func revokingDevice(id: String) -> Builder
public func withDelay(seconds: Int) -> Builder
public func withLivenessSettings(
livenessConfiguration: LivenessConfiguration,
livenessTimeout: Int
) -> Builder
public func withMessageToSign(_ message: String) -> Builder
public func withOperationInfo(
id: String,
payload: String? = nil,
externalUserId: String? = nil
) -> Builder
public func withPin(_ pin: String) -> Builder
public func withSuccessAnimation(_ enabled: Bool) -> Builder
public func build() -> AuthenticationConfiguration
}class BiomAuthConfig extends AuthConfig {
final LivenessConfiguration? livenessConfiguration;
final int? livenessTimeout;
final int? cameraDelaySeconds;
final bool? shouldRetrieveTemporaryState;
final String? b64NewDeviceData;
final String? b64OldDeviceData;
final String? deviceToRevoke;
final bool? shouldRetrieveSecret;
final bool? shouldRemovePin;
final JwtSigningInfo? jwtSigningInfo;
final DynamicLinkingInfo? dynamicLinkingInfo;
final OperationInfo? operationInfo;
final bool? showScreenSuccessFlow;
}class BiomAuthConfig {
public readonly shouldRemovePin: boolean;
public readonly cameraDelaySeconds: number;
public readonly showSuccessFeedback: boolean;
public readonly shouldRetrieveSecret: boolean;
public readonly shouldDeleteSecret: boolean;
public readonly jwtSigningInfo: JwtSigningInfo | null;
public readonly dynamicLinkingInfo: DynamicLinkingInfo | null;
public readonly livenessConfiguration: LivenessConfiguration;
public readonly livenessEnvironmentAware: boolean;
public readonly deviceToRevoke: string | null;
public readonly operationInfo: OperationInfo | null;
public readonly generatingClientState: ClientStateType | null;
public readonly shouldRetrieveAuthenticationFrame: boolean | null;
public readonly presentationStyle: PresentationStyle;
}
data class AuthenticationSuccess(
val clientState: String?,
val secret: KeylessSecret?,
val secretIDs: Set<KeylessSecret.Identifier>?,
val signedJwt: String?
) : KeylessSdkSuccess()public struct AuthenticationSuccess {
public let clientState: String?,
public let secret: KeylessSecret?
public let secretIDs: Set<KeylessSecret.Identifier>?
public let signedJwt: String?
}class AuthenticationSuccess {
final String? customSecret;
final String? signedJwt;
final String? temporaryState;
}class AuthenticationSuccess {
customSecret: string | null;
signedJwt: string | null;
clientState: string | null;
}val configuration = BiomAuthConfig(presentationStyle = PresentationStyle.NO_CAMERA_PREVIEW)
Keyless.authenticate(configuration = configuration, onCompletion = { result ->
// Handle result
})let configuration = BiomAuthConfig(presentationStyle: .noCameraPreview)
Keyless.authenticate(configuration: configuration, onCompletion: { result in
// Handle result
})import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
final configuration = BiomAuthConfig(presentationStyle: PresentationStyle.NO_CAMERA_PREVIEW);
try {
final result = await Keyless.instance.authenticate(configuration);
print("Authentication success");
} catch (error) {
print("Authentication failure");
}import Keyless, { BiomAuthConfig } from '@react-native-keyless/sdk';
const authenticateUserWithNoCameraPreview = async () => {
const configuration = new BiomAuthConfig({
presentationStyle: PresentationStyle.NO_CAMERA_PREVIEW,
});
const result = await Keyless.authenticate(configuration);
result.fold({
onSuccess: (data) => {
console.log('Authentication success', data);
},
onFailure: (error) => {
console.error('Authentication failure:', error);
},
});
};val configuration = AuthenticationConfiguration.builder.build()
Keyless.authenticate(
authenticationConfiguration = configuration,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "Authentication success")
is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "Authentication failure - error code ${result.error.code}")
}
}
)let configuration = Keyless.AuthenticationConfiguration.builder.build()
Keyless.authenticate(
authenticationConfiguration: configuration,
onCompletion: { result in
switch result {
case .success(let success):
print("Authentication success")
case .failure(let error):
break
}
})import 'package:keyless_flutter_sdk/keyless.dart';
import 'package:keyless_flutter_sdk/models/configurations/authentication_configuration.dart';
final configuration = BiomAuthConfig();
try {
final result = await Keyless.instance.authenticate(configuration);
print("Authentication success");
} catch (error) {
print("Authentication failure");
}import Keyless, { BiomAuthConfig } from '@react-native-keyless/sdk';
const authenticateUser = async () => {
const configuration = new BiomAuthConfig();
const result = await Keyless.authenticate(configuration);
result.fold({
onSuccess: (data) => {
console.log('Authentication success', data);
},
onFailure: (error) => {
console.error('Authentication failure:', error);
},
});
};val configuration = BiomAuthConfig()
Keyless.authenticate(
configuration = configuration,
onCompletion = { result ->
when (result) {
is Keyless.KeylessResult.Success -> Log.d("KeylessSDK ", "Authentication success")
is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "Authentication failure - error code ${result.error.code}")
}
}
)let configuration = BiomAuthConfig()
Keyless.authenticate(
configuration: configuration,
onCompletion: { result in
switch result {
case .success(let success):
print("Authentication success")
case .failure(let error):
break
}
})DEVELOPMENT
LEVEL_1 //recommended configuration
LEVEL_2val configuration = PinEnrollConfig(pin = "1234")
Keyless.enroll(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = PinEnrollConfig(pin: "1234")
Keyless.enroll(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)val configuration = EnrollmentConfiguration.builder
.withPin("1234")
.build()
Keyless.enroll(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = Keyless.EnrollmentConfiguration.builder
.withPin("1234")
.build()
Keyless.enroll(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)final configuration = PinEnrollConfig(
pin: "myPin"
);
try {
await Keyless.instance.enroll(configuration);
print("Enrollment successful");
} catch (error) {
print("Enrollment failed: $error");
}const config = new PinEnrollConfig({
pin: '1234',
});
const result = await Keyless.enroll(config);
result.fold({
onSuccess(data) {
logConsole('Auth result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Enroll result failure ' + JSON.stringify(error, null, 2));
},
});val configuration = PinAuthConfig(pin = "1234")
Keyless.authenticate(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = PinAuthConfig(pin: "1234")
Keyless.authenticate(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)val configuration = AuthenticationConfiguration.builder
.withPin("1234")
.build()
Keyless.authenticate(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = Keyless.AuthenticationConfiguration.builder
.withPin("1234")
.build()
Keyless.authenticate(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)final configuration = PinAuthConfig(
pin: "1234"
);
try {
final result = await Keyless.instance.authenticate(configuration);
print("Authentication successful");
} catch (error) {
print("Authentication failed: $error");
}const config = new PinAuthConfig({
pin: '1234',
});
const result = await Keyless.authenticate(config);
result.fold({
onSuccess(data) {
logConsole('Auth result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
},
});val configuration = PinDeEnrollConfig(pin = "1234")
Keyless.deEnroll(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = PinDeEnrollConfig(pin: "1234")
Keyless.deEnroll(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)val configuration =
DeEnrollmentConfiguration.builder
.withPin("myPin")
.build()
Keyless.deEnroll(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration =
Keyless.DeEnrollmentConfiguration.builder
.withPin("myPin")
.build()
Keyless.deEnroll(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)final configuration = PinDeEnrollConfig(
pin: "1234"
);
try {
await Keyless.instance.deEnroll(configuration);
print("De-enrollment successful");
} catch (error) {
print("De-enrollment failed: $error");
}const config = new PinDeEnrollConfig('1234');
const result = await Keyless.deEnroll(config);
result.fold({
onSuccess(data) {
logConsole('DeEnroll result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('DeEnroll result failure ' + JSON.stringify(error, null, 2));
},
});val configuration = BiomAuthConfig(shouldRemovePin = true)
Keyless.authenticate(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = BiomAuthConfig(shouldRemovePin: true)
Keyless.authenticate(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)val configuration =
AuthenticationConfiguration.builder
.removingPin()
.build()
Keyless.authenticate(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration =
Keyless.AuthenticationConfiguration.builder
.removingPin()
.build()
Keyless.authenticate(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)final configuration = BiomAuthConfig(
shouldRemovePin: true
);
try {
await Keyless.instance.authenticate(configuration);
print("Pin remove successful");
} catch (error) {
print("Pin remove failed: $error");
}
const config = new BiomAuthConfig({
shouldRemovePin: true,
});
const result = await Keyless.deEnroll(config);
result.fold({
onSuccess(data) {
logConsole('Auth result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
},
});val configuration = PinAuthConfig(pin = "1234", newPin = "5678")
Keyless.authenticate(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = PinAuthConfig(pin: "1234", newPin: "5678")
Keyless.authenticate(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)Future<void> changePin({
required String oldPin,
required String newPin
}) asyncconst config = new PinAuthConfig({
pin: '1234',
newPin: '5678',
});
const result = await Keyless.authenticate(config);
result.fold({
onSuccess(data) {
logConsole('Auth result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
},
});val configuration = PinAuthConfig(pin = "1234", shouldRemovePin = true)
Keyless.authenticate(
configuration = configuration,
onCompletion = { /*TODO: process result*/ }
)let configuration = PinAuthConfig(pin: "1234", shouldRemovePin: true)
Keyless.authenticate(
configuration: configuration,
onCompletion: { /*TODO: process result*/ }
)Future<void> removePin({
required String pin
}) asyncconst config = new PinAuthConfig({
pin: '1234',
shouldRemovePin: true,
});
const result = await Keyless.authenticate(config);
result.fold({
onSuccess(data) {
logConsole('Auth result success ' + JSON.stringify(data, null, 2));
},
onFailure(error) {
logConsole('Auth result failure ' + JSON.stringify(error, null, 2));
},
});showScreenSuccessFlowshowSuccessFeedbackAndroid: from keyless-android-sdk to keyless-mobile-sdk
iOS (SPM): from keyless.KeylessSDK to keyless.mobile-sdk
iOS (CocoaPods): from KeylessSDK to keyless-mobile-sdkThe Keyless SDK can be customised in order to provide a more familiar UX when integrated in any custom app.
Keyless.UI.Color.sdkTheme = SdkTheme.SYSTEM
// default theme is SYSTEM
public enum
Keyless.UI.Color.sdkTheme = .system
import Keyless, { SdkTheme } from '
showFailureFeedback: affects the Error screen (by default true)Keyless.UI.Color.primary = 0xFF1833B8
Keyless.UI.Color.onPrimary = 0xFFFED900Keyless.UI.Color.primary = .magenta
Keyless.UI.Color.onPrimary = .cyanfinal uiCustomization = UICustomization(
primaryColor: 0xFF1833B8,
onPrimaryColor: 0xFFFED900,
);
// Pass the UI customization when configuring the SDK
final setupConfiguration = SetupConfiguration(
apiKey: "YOUR_API_KEY",
hosts: ["YOUR_HOSTS"],
uiCustomization: uiCustomization
);// Custom text for enrollment
// prelimiar information for enrollment
Keyless.UI.Text.Enrollment.Step0.title = "(custom) Enroll your face"
Keyless.UI.Text.Enrollment.Step0.description = "(custom) On the next screen, we will take a photo of your face to create your account."
Keyless.UI.Text.Enrollment.Step0.prerequisiteCenterFace = "(custom) Center your face in the frame"
Keyless.UI.Text.Enrollment.Step0.prerequisiteDirectLook = "(custom) Look directly at the screen"
Keyless.UI.Text.Enrollment.Step0.prerequisiteWellLitArea = "(custom) Ensure you are in a well-lit area"
Keyless.UI.Text.Enrollment.Step0.prerequisiteRemoveEyeWear = "(custom) Remove any eyewear or hats"
Keyless.UI.Text.Enrollment.Step0.continueCta = "(custom) Continue"
// remaining steps of the enrollment
Keyless.UI.Text.Enrollment.Step1.text1 = "(custom) Put your face within the frame"
Keyless.UI.Text.Enrollment.Step1Success.message = "(custom) Photo captured successfully"
Keyless.UI.Text.Enrollment.Step2.text1 = "(custom 1) Enrolling, please wait…"
Keyless.UI.Text.Enrollment.Step2.text2 = "(custom 2) Enrolling, please wait…"
Keyless.UI.Text.Enrollment.Step2.text3 = "(custom 3) Enrolling, please wait…"
Keyless.UI.Text.Enrollment.Step3.text1 = "(custom) Keyless account created successfully!"
// Custom text for authentication
Keyless.UI.Text.Authentication.Step1.text1 = "(custom) Please look into the camera"
Keyless.UI.Text.Authentication.Step2.text1 = "(custom) Communicating with the Keyless network"
Keyless.UI.Text.Authentication.Step3.text1 = "(custom) Approved"
// Custom text for dynamic linking
Keyless.UI.Text.Authentication.PayloadConfirmation.title = "(custom) Authentication request"
Keyless.UI.Text.Authentication.PayloadConfirmation.subtitle = "(custom) Please, approve the payment to complete the process"
Keyless.UI.Text.Authentication.PayloadConfirmation.denyCta = "(custom) Deny"
Keyless.UI.Text.Authentication.PayloadConfirmation.approveCta = "(custom) Approve"// Custom text for enrollment
// prelimiar information for enrollment
Keyless.UI.Text.Enrollment.Step0.title = "(custom) Enroll your face"
Keyless.UI.Text.Enrollment.Step0.description = "(custom) On the next screen, we will take a photo of your face to create your account."
Keyless.UI.Text.Enrollment.Step0.prerequisiteCenterFace = "(custom) Center your face in the frame"
Keyless.UI.Text.Enrollment.Step0.prerequisiteDirectLook = "(custom) Look directly at the screen"
Keyless.UI.Text.Enrollment.Step0.prerequisiteWellLitArea = "(custom) Ensure you are in a well-lit area"
Keyless.UI.Text.Enrollment.Step0.prerequisiteRemoveEyeWear = "(custom) Remove any eyewear or hats"
Keyless.UI.Text.Enrollment.Step0.continueCta = "(custom) Continue"
// remaining steps of the enrollment
Keyless.UI.Text.Enrollment.Step1.text1 = "(custom) Put your face within the frame"
Keyless.UI.Text.Enrollment.Step1Success.message = "(custom) Position your face within the frame"
Keyless.UI.Text.Enrollment.Step2.text1 = "(custom 1) Enrolling, please wait…"
Keyless.UI.Text.Enrollment.Step2.text2 = "(custom 2) Enrolling, please wait…"
Keyless.UI.Text.Enrollment.Step2.text3 = "(custom 3) Enrolling, please wait…"
Keyless.UI.Text.Enrollment.Step3.text1 = "(custom) Keyless account created successfully!"
// Custom text for authentication
Keyless.UI.Text.Authentication.Step1.text1 = "(custom) Please look into the camera"
Keyless.UI.Text.Authentication.Step2.text1 = "(custom) Communicating with the Keyless network"
Keyless.UI.Text.Authentication.Step3.text1 = "(custom) Approved"
// Custom text for dynamic linking
Keyless.UI.Text.Authentication.PayloadConfirmation.title = "(custom) Authentication request"
Keyless.UI.Text.Authentication.PayloadConfirmation.subtitle = "(custom) Please, approve the payment to complete the process"
Keyless.UI.Text.Authentication.PayloadConfirmation.denyCta = "(custom) Deny"
Keyless.UI.Text.Authentication.PayloadConfirmation.approveCta = "(custom) Approve"final uiCustomization = UICustomization(
// Enrollment Step 0
enrollmentStep0Title: "(custom) Enroll your face",
enrollmentStep0Description: "(custom) On the next screen, we will take a photo of your face to create your account.",
enrollmentStep0PrerequisiteCenterFace: "(custom) Center your face in the frame",
enrollmentStep0PrerequisiteDirectLook: "(custom) Look directly at the screen",
enrollmentStep0PrerequisiteWellLitArea: "(custom) Ensure you are in a well-lit area",
enrollmentStep0PrerequisiteRemoveEyeWear: "(custom) Remove any eyewear or hats",
enrollmentStep0ContinueCta: "(custom) Continue",
// Enrollment Steps
enrollmentStep1Text: "(custom) Put your face within the frame",
enrollmentStep1SuccessText: "(custom) Photo captured successfully",
enrollmentStep2Text1: "(custom 1) Enrolling, please wait…",
enrollmentStep2Text2: "(custom 2) Enrolling, please wait…",
enrollmentStep2Text3: "(custom 3) Enrolling, please wait…",
enrollmentStep2Subtitle: "(custom) Processing your enrollment",
enrollmentStep3Text: "(custom) Keyless account created successfully!",
enrollmentStep3Subtitle: "(custom) You're all set!",
// Authentication Steps
authenticationStep1: "(custom) Please look into the camera",
authenticationStep2: "(custom) Communicating with the Keyless network",
authenticationStep3: "(custom) Approved",
);
// Pass the UI customization when configuring the SDK
final setupConfiguration = SetupConfiguration(
apiKey: "YOUR_API_KEY",
hosts: ["YOUR_HOSTS"],
uiCustomization: uiCustomization
);val biomEnrollConfig = BiomEnrollConfig(
showScreenInstructions = false,
showScreenSuccessFaceCapture = false,
showScreenSuccessFlow = false
)
Keyless.enroll(
configuration = biomEnrollConfig,
onCompletion = { /* handle completion */ }
)let biomEnrollConfig = BiomEnrollConfig(
showScreenSuccessFlow: false,
showScreenSuccessFaceCapture: false,
showScreenInstructions: false
)
Keyless.enroll(
configuration: biomEnrollConfig,
onCompletion: { _ in /* handle completion */ }
)val biomAuthConfig = BiomAuthConfig(
showScreenSuccessFlow = false
)
Keyless.authenticate(
configuration = biomAuthConfig,
onCompletion = { /* handle completion */ }
)let biomAuthConfig = BiomAuthConfig(
showScreenSuccessFlow: false
)
Keyless.authenticate(
configuration: biomAuthConfig,
onCompletion: { _ in /* handle completion */ }
)Keyless.UI.Font.customFont: Typeface = Typeface.SERIFKeyless.UI.Font.customFont: String = "Serif"final uiCustomization = UICustomization(
customFont: "Serif"
);// Custom text for introduction
Keyless.UI.Text.Introduction.title = "(custom) Keyless Secure Authentication"
Keyless.UI.Text.Introduction.description = "(custom) Hereon, you will start face scanning..."
Keyless.UI.Text.Introduction.cta = "(custom) Continue"
// Custom text for enrollment
// prelimiar information for enrollment
Keyless.UI.Text.Enrollment.Instruction.title = "(custom) Enroll your face"
Keyless.UI.Text.Enrollment.Instruction.description = "(custom) On the next screen, we will take a photo of your face to create your account."
Keyless.UI.Text.Enrollment.Instruction.tip1 = "(custom) Center your face in the frame"
Keyless.UI.Text.Enrollment.Instruction.tip2 = "(custom) Look directly at the screen"
Keyless.UI.Text.Enrollment.Instruction.tip3 = "(custom) Ensure you are in a well-lit area"
Keyless.UI.Text.Enrollment.Instruction.continueCta = "(custom) Continue"
// Enrollment loading screen
Keyless.UI.Text.Enrollment.Process.title = "(custom 1) Hold on a few seconds"
Keyless.UI.Text.Enrollment.Process.subtitle = "(custom 2) We're creating your private key"
// Error screen
Keyless.UI.Text.Enrollment.Error.title = "(custom) Something went wrong"
Keyless.UI.Text.Enrollment.Error.subtitle = "(custom) Please try again"
Keyless.UI.Text.Enrollment.Error.cta = "(custom) Continue"
// Success screen
Keyless.UI.Text.Enrollment.Success.title = "(custom) Keyless account created successfully!"
Keyless.UI.Text.Enrollment.Success.subtitle = "(custom) Keyless account created successfully!"
Keyless.UI.Text.Enrollment.Success.cta = "(custom) Keyless account created successfully!"
// Custom text for authentication
Keyless.UI.Text.Authentication.Step1.text1 = "(custom) Please look into the camera"
Keyless.UI.Text.Authentication.Step2.text1 = "(custom) Communicating with the Keyless network"
Keyless.UI.Text.Authentication.Step3.text1 = "(custom) Approved"
// Custom text for authentication without camera preview available from version 5.4.1
Keyless.UI.Text.Authentication.NoCameraPreview.lookHere = "(custom) Please look into the camera"
Keyless.UI.Text.Authentication.NoCameraPreview.authenticate = "(custom) Communicating with the Keyless network"
Keyless.UI.Text.Authentication.NoCameraPreview.success = "(custom) Approved"
// Custom text for dynamic linking
Keyless.UI.Text.Authentication.PayloadConfirmation.title = "(custom) Authentication request"
Keyless.UI.Text.Authentication.PayloadConfirmation.subtitle = "(custom) Please, approve the payment to complete the process"
Keyless.UI.Text.Authentication.PayloadConfirmation.denyCta = "(custom) Deny"
Keyless.UI.Text.Authentication.PayloadConfirmation.approveCta = "(custom) Approve"
// Custom text for introduction
Keyless.UI.Text.Introduction.title = "(custom) Keyless Secure Authentication"
Keyless.UI.Text.Introduction.description = "(custom) Hereon, you will start face scanning..."
Keyless.UI.Text.Introduction.cta = "(custom) Continue"
// Custom text for enrollment
// Prelimiar information for enrollment
Keyless.UI.Text.Enrollment.Instruction.title = "(custom) Enroll your face"
Keyless.UI.Text.Enrollment.Instruction.description = "(custom) On the next screen, we will take a photo of your face to create your account."
Keyless.UI.Text.Enrollment.Instruction.tip1 = "(custom) Center your face in the frame"
Keyless.UI.Text.Enrollment.Instruction.tip2 = "(custom) Look directly at the screen"
Keyless.UI.Text.Enrollment.Instruction.tip3 = "(custom) Ensure you are in a well-lit area"
Keyless.UI.Text.Enrollment.Instruction.continueCta = "(custom) Continue"
// Enrollment loading screen
Keyless.UI.Text.Enrollment.Process.title = "(custom 1) Hold on a few seconds"
Keyless.UI.Text.Enrollment.Process.subtitle = "(custom 2) We're creating your private key"
// Error screen
Keyless.UI.Text.Enrollment.Error.title = "(custom) Something went wrong"
Keyless.UI.Text.Enrollment.Error.subtitle = "(custom) Please try again"
Keyless.UI.Text.Enrollment.Error.cta = "(custom) Continue"
// Success screen
Keyless.UI.Text.Enrollment.Success.title = "(custom) Keyless account created successfully!"
Keyless.UI.Text.Enrollment.Success.subtitle = "(custom) Keyless account created successfully!"
Keyless.UI.Text.Enrollment.Success.cta = "(custom) Keyless account created successfully!"
// Custom text for authentication
Keyless.UI.Text.Authentication.Step1.text1 = "(custom) Please look into the camera"
Keyless.UI.Text.Authentication.Step2.text1 = "(custom) Communicating with the Keyless network"
Keyless.UI.Text.Authentication.Step3.text1 = "(custom) Approved"
// Custom text for authentication without camera preview available from version 5.4.1
Keyless.UI.Text.Authentication.NoCameraPreview.lookHere = "(custom) Please look into the camera"
Keyless.UI.Text.Authentication.NoCameraPreview.authenticate = "(custom) Communicating with the Keyless network"
Keyless.UI.Text.Authentication.NoCameraPreview.success = "(custom) Approved"
// Custom text for dynamic linking
Keyless.UI.Text.Authentication.PayloadConfirmation.title = "(custom) Authentication request"
Keyless.UI.Text.Authentication.PayloadConfirmation.subtitle = "(custom) Please, approve the payment to complete the process"
Keyless.UI.Text.Authentication.PayloadConfirmation.denyCta = "(custom) Deny"
Keyless.UI.Text.Authentication.PayloadConfirmation.approveCta = "(custom) Approve"import Keyless from '@react-native-keyless/sdk';
import Keyless from '@react-native-keyless/sdk';
const ui = new Keyless.UI();
// Custom text for introduction
ui.text.introduction.title = '(custom) Keyless Secure Authentication';
ui.text.introduction.description = '(custom) Hereon, you will start face scanning...';
ui.text.introduction.cta = '(custom) Continue';
// Custom text for enrollment
// Prelimiar information for enrollment
ui.text.enrollment.instruction.title = '(custom) Enroll your face';
ui.text.enrollment.instruction.tip1 = '(custom) Center your face in the frame';
ui.text.enrollment.instruction.tip2 = '(custom) Look directly at the screen';
ui.text.enrollment.instruction.tip3 = '(custom) Ensure you are in a well-lit area';
ui.text.enrollment.instruction.continueCta = '(custom) Continue';
// Enrollment loading screen
ui.text.enrollment.process.title = '(custom) Hold on a few seconds';
ui.text.enrollment.process.subtitle = "(custom) We're creating your private key";
// Error screen
ui.text.enrollment.error.title = '(custom) Something went wrong';
ui.text.enrollment.error.subtitle = '(custom) Please try again';
ui.text.enrollment.error.cta = '(custom) Continue';
// Success screen
ui.text.enrollment.success.title = '(custom) Keyless account created successfully!';
ui.text.enrollment.success.subtitle = '(custom) Keyless account created successfully!';
ui.text.enrollment.success.cta = '(custom) Keyless account created successfully!';
// Custom text for authentication
ui.text.authentication.centerFace = '(custom) Please look into the camera';
ui.text.authentication.scan = '(custom) Communicating with the Keyless network';
ui.text.authentication.authenticate = '(custom) Approved';
ui.text.authentication.success = '(custom) Approved';
ui.text.authentication.loading = '(custom) Loading';
// Custom text for dynamic linking
ui.text.authentication.payloadConfirmation.title = '(custom) Authentication request';
ui.text.authentication.payloadConfirmation.subtitle = '(custom) Please, approve the payment to complete the process';
ui.text.authentication.payloadConfirmation.denyCta = '(custom) Deny';
ui.text.authentication.payloadConfirmation.approveCta = '(custom) Approve';
await Keyless.updateUI(ui);// To hide all optional screens
val biomEnrollConfig = BiomEnrollConfig(
showInstructionsScreen = false,
showSuccessFeedback = false,
showFailureFeedback = false
)
Keyless.enroll(
configuration = biomEnrollConfig,
onCompletion = { /* handle completion */ }
)// To hide all optional screens
let biomEnrollConfig = BiomEnrollConfig(
showInstructionsScreen: false,
showSuccessFeedback: false,
showFailureFeedback: false
)
Keyless.enroll(
configuration: biomEnrollConfig,
onCompletion: { _ in /* handle completion */ }
)import Keyless, { BiomEnrollConfig } from '@react-native-keyless/sdk';
const enrollConfig = new BiomEnrollConfig({
showScreenInstructions: false,
showSuccessFeedback: false,
showFailureFeedback: false
});
const result = await Keyless.enroll(enrollConfig);val biomAuthConfig = BiomAuthConfig(
showSuccessFeedback = false
)
Keyless.authenticate(
configuration = biomAuthConfig,
onCompletion = { /* handle completion */ }
)let biomAuthConfig = BiomAuthConfig(
showSuccessFeedback: false
)
Keyless.authenticate(
configuration: biomAuthConfig,
onCompletion: { _ in /* handle completion */ }
)import Keyless, { BiomAuthConfig } from '@react-native-keyless/sdk';
const config = new BiomAuthConfig({
showSuccessFeedback: false,
});
const result = await Keyless.enroll(config);Keyless.UI.Font.customFont: Typeface = Typeface.SERIFKeyless.UI.Font.customFont: String = "Serif"Keyless.UI.hapticFeedbackEnabled = trueKeyless.UI.hapticFeedbackEnabled = falseKeyless.UI.Color.sdkTheme = SdkTheme.SYSTEM
// default theme is SYSTEM
public enum class SdkTheme {
DARK,
LIGHT,
SYSTEM
}Keyless.UI.Color.sdkTheme = .system
// default theme is system
public enum SDKTheme {
case dark
case light
case system
}








Keyless.UI.Color.primary = 0xFF1833B8
Keyless.UI.Color.onPrimary = 0xFFFED900
Keyless.UI.Color.accent = 0xFFFED900Keyless.UI.Color.primary = .magenta
Keyless.UI.Color.onPrimary = .cyan
Keyless.UI.Color.accent = .yellowconst ui = new Keyless.UI();
ui.color.accent = '#1833B8';
ui.color.primary ='#FFFFFF';
ui.color.accent = '#FED900';
await Keyless.updateUI(ui);




