# Generating client state via the Mobile SDK

## What is the client state?

The Keyless *client state* contains all the necessary information to restore an account. It can be created during enrollment and authentication

{% hint style="info" %}
To create and use the client state Keyless requires the user's biometric to be authenticated.
{% endhint %}

The temporay state internals are not important but you can expect a string similar to the following that you should pass as-is to recover the account:

```json
"{\"artifact\":{\"family\":\"davideface_lite\",\"version\":\"1.2.0\",\"target\":\"mobile_sdk\",\"liveness\":\"liveness\"},\"core-client-state\":\"BASE_64_STATE\"}"
```

{% hint style="warning" %}
Note that when generating the client state within your client app using the Keyless Mobile SDK a maximum of 50 client states are allowed to be generated. This ensures that the experience remains performant.
{% endhint %}

## Obtain the client state

Use the `generatingClientState` parameter of the `BiomEnrollConfig` or `BiomAuthConfig`. When doing so, we recommend choosing `BACKUP` as the client state type to be generated. Note: if you’re using Flutter, this parameter will instead be named `shouldRetrieveTemporaryState`.

{% tabs %}
{% tab title="Android" %}
Dunring the enrollment flow:

```kotlin
val enrollConfig = BiomEnrollConfig(generatingClientState = ClientStateType.BACKUP)

Keyless.enroll(
  configuration = enrollConfig,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> {

      	val clientState = result.value.clientState
      	// store the client state on your backend to recover the account in the future

      }
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
    }
  }
)

```

During the authentication flow:

```kotlin
val authConfig = BiomAuthConfig(generatingClientState = ClientStateType.BACKUP)

Keyless.authenticate(
  configuration = authConfig,
  onCompletion = { result ->
    when (result) {
      is Keyless.KeylessResult.Success -> {

      	val clientState = result.value.clientState
      	// store the client state on your backend to recover the account in the future

      }
      is Keyless.KeylessResult.Failure -> Log.d("KeylessSDK ", "error code ${result.error.code}")
    }
  }
)
```

{% endtab %}

{% tab title="iOS" %}
During the enrollment flow:

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

During the authentication flow:

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

{% endtab %}

{% tab title="Flutter" %}
During the enrollment flow:

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

During the authentication flow:

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

{% endtab %}

{% tab title="React Native" %}
During the enrollment flow:

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

During the authentication flow:

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

{% endtab %}
{% endtabs %}
