# 1️⃣ Getting started

In this short guide, you will learn how to integrate the Keyless SDK in your Android or iOS mobile application, and enroll and authenticate users through the Keyless platform.

Before jumping into your code editor, make sure that you're familiar with the various [components](https://docs.keyless.io/consumer/introduction/components) of the authentication system, and common biometic [authentication flows](https://docs.keyless.io/consumer/introduction/integration-flows).

## Prerequisites

Make sure you have both required API keys, and the list of productions hosts from your Keyless contact:

* `YOUR_CLOUDSMITH_TOKEN` to download the SDK from cloudsmith repository
* `KEYLESS_API_KEY` to configure the mobile SDK
* `KEYLESS_HOSTS` a list of node URLs. Urls in `KEYLESS_HOSTS` must NOT contain any trailing slashes `/`.

Review the Keyless SDK requirements:

{% tabs %}
{% tab title="Android" %}
The Keyless SDK uses

* [Android 6.0](https://developer.android.com/about/versions/marshmallow) (API level 23) and above
* [Kotlin 1.9.25](https://github.com/JetBrains/kotlin/releases/tag/v1.9.25)
* [Gradle 8.7](https://docs.gradle.org/8.7/release-notes.html)
* [Android Gradle Plugin 8.3.0](https://developer.android.com/build/releases/past-releases/agp-8-3-0-release-notes)
* [AndroidX](https://developer.android.com/jetpack/androidx/)
  {% endtab %}

{% tab title="iOS" %}
The Keyless SDK uses

* [iOS 13](https://developer.apple.com/documentation/ios-ipados-release-notes/ios-13-release-notes)
* [Swift 5.1](https://www.swift.org/swift-evolution/#?version=5.1)
* [Cocoapods 1.15.2](https://github.com/CocoaPods/CocoaPods/releases/tag/1.15.2)

Set up a physical iOS device for running your app and enable the following permissions:

* Enable Camera permissions: add the `Privacy - Camera Usage Description` key in your project’s `Info.plist` by adding the following (in XCode under Project > Info):

  ```xml
  <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>
  ```
* Enable background processing: necessary to synchronize Keyless data. You can find a comprehensive guide in the [apple documentation](https://developer.apple.com/documentation/UIKit/using-background-tasks-to-update-your-app). In a nutshell here is what you need to do: enable the `Background processing` mode under `Signing & Capabilities/Background Modes`. Then, add the following in your project’s `Info.plit` (in XCode, under the key `Permitted background task scheduler identifiers`):

  ```xml
  <key>NSCameraUsageDescription</key>
  <key>BGTaskSchedulerPermittedIdentifiers</key>
  <array>
      <string>YOUR APP IDENTIFIER</string>
  </array>
  ```

{% endtab %}

{% tab title="Flutter" %}
The Keyless SDK uses

* [Flutter 3.0](https://docs.flutter.dev/release/release-notes/release-notes-3.0.0) or higher
* [Dart 3.0](https://dart.dev/guides/whats-new#dart-3) or higher
* All requirements from both Android and iOS platforms

Set up the required permissions as described in the Android and iOS tabs.
{% endtab %}

{% tab title="React Native" %}
The Keyless RN SDK requires:

* [React 18.2.0](https://www.google.com/search?q=https://github.com/facebook/react/blob/main/CHANGELOG.md%231820-june-14-2022) or higher
* [React Native 0.71.0](https://reactnative.dev/docs/0.71/getting-started) or higher

Additionally, ensure you meet the native requirements for each platform:

* **Android**: Minimum SDK 23 (Android 6.0), Kotlin `2.2.0` or higher.
* **iOS**: Target version `13.0` or higher.
  {% endtab %}
  {% endtabs %}

## Installation

{% hint style="info" %}
**Keyless Anti-Inject variant for enhanced frames injection prevention**

If you are using the anti-inject SDK variant with runtime application self protection - RASP, you need to:

* Set the package repository `partners-rasp-*` communicated to you by our Delivery team.
* Add into your app assets the `license` file provided to you by our Delivery team.
  {% endhint %}

{% tabs %}
{% tab title="Android - Gradle" %}

1. To allow Keyless to handle the result of [registerForActivityResult](https://developer.android.com/training/basics/intents/result#register), you must call Keyless from an Activity implementing [ActivityResultCaller](https://developer.android.com/reference/androidx/activity/result/ActivityResultCaller).

   Extend any androidX activity that implements the interface for you, for example let your Activity extend the generic [ComponentActivity](https://developer.android.com/reference/androidx/activity/ComponentActivity) or the more widespread [AppCompatActivity](https://developer.android.com/reference/androidx/appcompat/app/AppCompatActivity).
2. If you use Proguard, add the following rules to your Proguard configuration file:

   ```
   # Keyless Proguard
   -keep class io.keyless.sdk.** {*;}
   -keepclassmembers class io.keyless.sdk.** {*;}
   ```
3. In the `repositories` section of the `settings.gradle` file of your Android application, add the following snippet, replacing `YOUR_CLOUDSMITH_TOKEN` with the CloudSmith token provided to you by Keyless.

   ```kotlin
   dependencyResolutionManagement {
       repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
       repositories {
           google()
           mavenCentral()
           maven {
               url "https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/maven/"
           }
       }
   }
   ```
4. In the `dependencies` block of your project `build.gradle` file, typically `app/build.gradle`, add:

   ```kotlin
   dependencies {
   // ...

   implementation 'io.keyless:keyless-mobile-sdk:+'
   }
   ```
5. In the `android` block of your project `build.gradle` file, typically `app/build.gradle`, make sure you have the following options:

   ```kotlin
   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"
       }
   }
   ```

{% endtab %}

{% tab title="iOS - SPM" %}
We use Cloudsmith to distribute our artifacts. Cloudsmith works as a Swift Package Registry. In order to use packages from a registry, one has to set up the environment for that specific registry and possibly log in to it.

When working with Swift Projects, registries can be configured locally to the project. Unfortunately, though, Xcode does not support local configuration of registries, thus they have to be configured globally, for the editor to be able to see them.

{% hint style="warning" %}
It's best to run all the following commands from terminal with Xcode closed
{% endhint %}

To configure Keyless Cloudsmith Package Registry, you can run the following commands in your terminal

```bash
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>
```

You will also be provided with a token to put in place of `<your-api-token>` to access the partners repo.

Since you are adding this registry as global, it is important to provide the scope `keyless` for Keyless Package registry.

These commands add the following to your `~/.swiftpm/configurations/registries.json`

```json
 {
  "authentication" : {
    "swift.cloudsmith.io" : {
      "loginAPIPath" : "/keyless/<repo>",
      "type" : "token"
    }
  },
  "registries" : {
    "keyless" : {
      "supportsAvailability" : false,
      "url" : "https://swift.cloudsmith.io/keyless/<repo>/"
    }
  "version" : 1
}
```

Once you have this setup, you can open Xcode, go to **File → Add Package Dependencies** and a wizard will open to prompt the insertion of the package.

In the top-right bar, you can search for the package, e.g. **keyless.mobile-sdk**, and if everything is setup correctly, the package should appear in the center column. You can add the package to the project and proper targets and you are ready to go.

**Optional - Test release candidates**

We provide our partners the chance to test Release candidates before they receive the final approval of our whole QA process. Since release candidates are stored in a separate repo and Xcode does not cope well with Semantic versioning with build numbers (which our release candidates use), we suggest to:

1. Manually download the Package from Cloudsmith, using your assigned token
2. Extract the archive. It should unpack in a folder called `KeylessSDKPackage`
3. Drag-and-drop the extracted folder inside your Xcode project, exactly under the root of the project file.

Once dropped inside your project, if you already had a Keyless SDK Package configured with the first method, this is going to be substituted by the local one seamlessly. If not, then just add the `KeylessSDK` library to your target from the project settings.
{% endtab %}

{% tab title="iOS - Cocoapods" %}
{% hint style="warning" %}
Since Cocoapods is in **maintenance mode**, this method is going to be discontinued. Please integrate Keyless via **SPM**
{% endhint %}

1. Create a Podfile if you don’t already have one

   ```bash
   $ cd your-project-directory
   $ pod init
   ```
2. Add the `keyless-mobile-sdk` pod to your `Podfile`

   ```ruby
   # 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'
   end
   ```
3. Add the following at the bottom of your `Podfile`

   ```ruby
   post_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
   ```
4. Install the pods.

   ```bash
   $ 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`
   ```

{% endtab %}

{% tab title="Flutter" %}

1. Add the Keyless SDK repository

   ```bash
   echo '${CLOUDSMITH_TOKEN}' | dart pub token add https://dart.cloudsmith.io/keyless/flutter/
   ```
2. Add the Keyless SDK dependency to your `pubspec.yaml`:

   ```bash
   dart pub add keyless_flutter_sdk:PACKAGE_VERSION --hosted-url https://dart.cloudsmith.io/keyless/flutter/
   ```
3. Follow the installation steps in both the Android and iOS tabs to set up the native SDKs in their respective platforms.
4. Run flutter pub get to download the dependencies:

   ```bash
   flutter pub get
   ```

You also need to bridge the native SDKs that are used by the flutter SDK. You can do that in the `android` and `ios` sections of your flutter project.

**Android**

Add the following line in the root `build.gradle`:

```groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            setUrl("https://dl.cloudsmith.io/YOUR_CUSTOM_TOKEN/keyless/partners/maven/")
        }
    }
}  
```

Where `YOUR_CUSTOM_TOKEN` should be replaced with the cloudsmith token provided by the Keyless integration support team.

In the example repo you can see that we are using a file to simulate env properties containing the cloudsmith token. You will read the following snippet:

```groovy
allprojects {
    repositories {
        google()
        mavenCentral()
        maven {
            setUrl("https://dl.cloudsmith.io/$cloudsmithToken/keyless/partners/maven/")
        }
    }
}
```

You can read the cloudsmith token from a file `cloudsmith.properties` that you need to create at the root project directory.\
File content shall be the following: `cloudsmithToken=YOUR_CUSTOM_TOKEN`

Then, open your `Android.manifest` file and add the following lines inside the `<application>` tag:

```xml
        <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>
```

**iOS**

Make sure to target at least iOS 13 in your project.

Open your `PodFile` and add the following line:

```bash
source 'https://dl.cloudsmith.io/YOUR_CUSTOM_TOKEN/keyless/partners/cocoapods/index.git'
```

Where `YOUR_CUSTOM_TOKEN` should be replaced with the cloudsmith token provided by the Keyless integration support team.

In the example repo you can see that we are using a file to simulate env properties containing the cloudsmith token. You will read the following snippet:

```bash
source 'https://dl.cloudsmith.io/'+ ENV['cloudsmithToken'] +'/keyless/partners/cocoapods/index.git'
```

File content shall be the following: `cloudsmithToken=YOUR_CUSTOM_TOKEN`

Then, navigate to your `Info.plist` file, typically located in a folder called with your project name (e.g. `Runner`).

Add the following permissions declaration to this file (if not present already):

```xml
<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>   
```

{% endtab %}

{% tab title="React Native" %}
**1. Configure Access to the Private Registry**

Create a `.npmrc` file in the root of your project. This file will tell your package manager where to find the Keyless SDK and how to authenticate. Add the following lines:

```bash
@react-native-keyless:registry=https://npm.cloudsmith.io/keyless/partners-rc/
//npm.cloudsmith.io/keyless/partners/:_authToken=YOUR_CLOUDSMITH_TOKEN
```

**Note:** Replace `YOUR_CLOUDSMITH_TOKEN` with the actual token provided to you.

**2. Add the Keyless SDK Dependency**

Run one of the following commands in your project's terminal to install the **latest** version of the SDK.

```bash
# Using npm
npm install @react-native-keyless/sdk

# Using yarn
yarn add @react-native-keyless/sdk
```

After installing the package, follow the setup steps for each native platform below.

***

**Android Setup**

1. **Add the Maven Repository**: Add the Keyless Maven repository to your root `build.gradle` file:

   ```groovy
   allprojects {
       repositories {
           google()
           mavenCentral()
           maven {
               url "https://dl.cloudsmith.io/YOUR_CLOUDSMITH_TOKEN/keyless/partners/maven/"
           }
       }
   }
   ```

   **Note:** Replace `YOUR_CLOUDSMITH_TOKEN` with your token.
2. **Verify Kotlin Version**: The Keyless SDK requires a minimum **Kotlin version of `2.2.0`**. Depending on your React Native project's configuration, this is specified in one of two files.
   * **If your project uses `settings.gradle` for plugins (modern setup):** Open your `android/settings.gradle` file and ensure the version for `org.jetbrains.kotlin.android` is `2.2.0` or higher.

     ```groovy
     // 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
         }
     }
     ```
   * **If your project uses `build.gradle` for plugins (older setup):** Open your root `android/build.gradle` file. The `kotlinVersion` variable is defined in the `ext` block and then used in the `dependencies` block. Please check if kotlin version is `2.2.0` or higher.

     ```groovy
     // 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
         }
     }
     ```

***

**iOS Setup**

1. **Target iOS 13 or Higher**: In your `ios/Podfile`, ensure the platform version is set to `13.0` or higher: `platform :ios, '13.0'`.
2. **Add the Private Spec Repo**: Open your `ios/Podfile` and add the Keyless Cocoapods source at the top of the file:

   ```ruby
   # 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/'
   ```

   **Note:** Replace `YOUR_CLOUDSMITH_TOKEN` with your token.
3. **Enable Camera Permissions**: Open your `ios/Info.plist` file and add the camera usage description.

   ```xml
   <key>NSCameraUsageDescription</key>
   <string>This app uses the camera to scan face.</string>
   ```
4. **Install Native Dependencies**: Navigate to the `ios` directory and run `pod install`.

   ```bash
   cd ios && pod install
   ```

{% endtab %}
{% endtabs %}

## Essential configuration

There is some essential configuration to do before you can use the Keyless SDK.

{% tabs %}
{% tab title="Android" %}

1. Initialize the Keyless SDK in your `Application` class:

   ```kotlin
   // MainApplication
   override fun onCreate() {
       super.onCreate()
       // Initialize Keyless
       Keyless.initialize(this)
   }
   ```

{% hint style="warning" %}
If your application crashes due to `java.lang.IllegalStateException: Attempting to launch an unregistered ActivityResultLauncher` or while using React/Native bridges you can't receive a completion result at the end of an enrollment, it may be due to a difference between your `applicationId` and the `namespace` of your activities.

In such case, the `Keyless.initialize(...)` accepts a second parameter which is the `namespace` you are currently using for your `Activities`. Providing this parameter should fix the issue.

Example:\
`namespace`: my.app.test\
`applicationId`: my.app.test.extra

```kotlin
  // MainApplication
  override fun onCreate() {
      super.onCreate()
      // Initialize Keyless
      Keyless.initialize(this, "my.app.test")
  }
```

Since we only check that the `namespace` of the Activity contains the `namespace` provided as input, `.app` or `my.app` are also valid inputs.
{% endhint %}

2. Add your application to the Manifest

   ```xml
   <application
       ...
       android:name=".MainApplication"
       ...
   </application>
   ```
3. Configure the Keyless SDK from your `MainActivity`, `ViewModel` or any class you use to communicate with `Keyless`. Note that `configure` is asynchronous so wait for the completion callback before calling the next Keyless APIs

   The `configure` method requires a `SetupConfig` as parameter, as well as the `KEYLESS_API_KEY` and `KEYLESS_HOSTS` you received from Keyless. You should listen to the result as follows:

   ```kotlin
   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
            }
        }
    }
   ```

{% endtab %}

{% tab title="iOS" %}

1. Create an instance object of `Keyless.SetupConfiguration` and pass it to the `Keyless.configure` method, typically this is done in your app’s `application(:didFinishLaunchingWithOptions: method:).`

   ```swift
   let setupConfig = SetupConfig(
           apiKey: "KEYLESS_API_KEY",
           hosts: ["KEYLESS_HOSTS"]
       )

   if let error = Keyless.configure(configuration: setupConfig) {
       print("Keyless.Configure failed with error: \(error)")
   }
   ```

{% endtab %}

{% tab title="Android v4.6" %}

1. Initialize the Keyless SDK in your `Application` class:

   ```kotlin
   // MainApplication
   override fun onCreate() {
       super.onCreate()
       // Initialize Keyless
       Keyless.initialize(this)
   }
   ```
2. Add your application to the Manifest

   ```xml
   <application
       ...
       android:name=".MainApplication"
       ...
   </application>
   ```
3. Configure the Keyless SDK from your `MainActivity`, `ViewModel` or any class you use to communicate with `Keyless`. Note that `configure` is asynchronous so wait for the completion callback before calling the next Keyless APIs

   The `configure` method requires a `SetupConfiguration` as parameter, as well as the `KEYLESS_API_KEY` and `KEYLESS_HOSTS` you received from Keyless. You should listen to the result as follows:

   ```kotlin
   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
            }
        }
    }
   ```

{% endtab %}

{% tab title="iOS v4.6" %}

1. Create an instance object of `Keyless.SetupConfiguration` and pass it to the `Keyless.configure` method, typically this is done in your app’s `application(:didFinishLaunchingWithOptions: method:).`

   ```swift
   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)")
   }
   ```

{% endtab %}

{% tab title="Flutter" %}

1. Import the required packages:

   ```dart
   import 'package:keyless_flutter_sdk/keyless.dart';
   import 'package:keyless_flutter_sdk/models/configurations/setup_configuration.dart';
   ```
2. Configure the Keyless SDK in your app's initialization code:

   ```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
   }
   ```
3. Make sure to set up the required permissions in both Android and iOS platforms as described in their respective tabs.
   {% endtab %}

{% tab title="React Native" %}

1. **Initialize the Native SDK for Android**: Open your `MainApplication.kt` (or `.java`) file and add call to `KeylessSDKModule.initialize()` inside the `onCreate` method.

   ```kotlin
   // 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
   }
   ```

{% hint style="warning" %}
If your application crashes due to `java.lang.IllegalStateException: Attempting to launch an unregistered ActivityResultLauncher` or while using React/Native bridges you can't receive a completion result at the end of an enrollment, it may be due to a difference between your `applicationId` and the `namespace` of your activities.

In such case, the `KeylessSDKModule.initialize(...)` accepts a second parameter which is the `namespace` you are currently using for your `Activities`. Providing this parameter should fix the issue.

Example:\
`namespace`: my.app.test\
`applicationId`: my.app.test.extra

```kotlin
    // 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
}  
```

Since we only check that the `namespace` of the Activity contains the `namespace` provided as input, `.app` or `my.app` are also valid inputs.
{% endhint %}

2. **Configure the Keyless SDK:** This is best done once when your application starts, after the native SDK has been initialized.

   Call the `configure` method with your credentials. The method returns a result object that you can handle using the `fold` method.

   ```javascript
   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);
     },
   });
   ```

{% endtab %}
{% endtabs %}

## Additional configuration

As well as the essential configuration parameters, you can also specify the *optional* configuration parameters detailed in the following sections. Details of these configuration options can be summarised in the relevant sections throughout the Mobile SDK (i.e. [Logging](https://docs.keyless.io/consumer/mobile-sdk-reference/logging), [Liveness Settings](https://docs.keyless.io/consumer/mobile-sdk-reference/liveness-settings) etc.) and you can inspect the Config class to see optional parameters (or the builder to see exposed methods).\
\
Some of the more the more generic configurations are described below for convenience.

### Shared circuits

This is the target desired number of circuits kept on the server. To set this number use the `numberOfSharedCircuits`.

### Networking module

If you need to perform network requests on behalf of the Keyless SDK, you can implement the `KLNetworkingModule` interface. Set the `networkingModule` parameter with an instance of the `KLNetworkingModule`:

{% tabs %}
{% tab title="Android" %}

```kotlin
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
    )
}
```

{% endtab %}

{% tab title="iOS" %}

```swift
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
    }
}
```

{% endtab %}
{% endtabs %}
