diff --git a/docs/kotlin-multiplatform-sdk/context-manager.md b/docs/kotlin-multiplatform-sdk/context-manager.md
index 5525b321..79c9ed77 100644
--- a/docs/kotlin-multiplatform-sdk/context-manager.md
+++ b/docs/kotlin-multiplatform-sdk/context-manager.md
@@ -7,628 +7,1321 @@ required when setting the operation context, authentication tokens, and other se
All the values that are provided to the context manager are automatically stored in [secure storage](initialize.md#secure-storage).
:::
-## Set operation context
+## Set API environment
+
+Changes the environment the SDK operates against. It can be changed at any time, although it is recommended to
+set it up through the [SdkConfig builder](initialize.md#sdk-config-builder) instead.
+
+
+
+
+```kotlin showLineNumbers
+sdk.contextManager().setApiEnvironment(ApiEnvironment.PROD)
+```
+
+
+
+
+```java showLineNumbers
+sdk.contextManager().setApiEnvironment(ApiEnvironment.PROD);
+```
+
+
+
+
+```swift showLineNumbers
+sdk.contextManager().setApiEnvironment(apiEnvironment: ApiEnvironment.prod)
+```
+
+
+
+
+```js showLineNumbers
+sdk.contextManager().setApiEnvironment("PROD");
+```
+
+
+
+
+```csharp showLineNumbers
+// Not implemented yet
+```
+
+
+
+
+```python showLineNumbers
+// Not implemented yet
+```
+
+
+
+
+## Get API environment
+
+Returns the environment the SDK is currently operating against. Defaults to `PROD` when it has never been set.
+
+
+
+
+```kotlin showLineNumbers
+// Returns an ApiEnvironment
+val apiEnvironment = sdk.contextManager().getApiEnvironment()
+```
+
+
+
+
+```java showLineNumbers
+// Returns an ApiEnvironment
+var apiEnvironment = sdk.contextManager().getApiEnvironment();
+```
+
+
+
+
+```swift showLineNumbers
+// Returns an ApiEnvironment
+let apiEnvironment = sdk.contextManager().getApiEnvironment()
+```
+
+
+
+
+```js showLineNumbers
+// Returns a string
+const apiEnvironment = sdk.contextManager().getApiEnvironment();
+```
+
+
+
+
+```csharp showLineNumbers
+// Returns an ApiEnvironment
+var apiEnvironment = sdk.GetContextManager().GetApiEnvironment();
+```
+
+
+
+
+```python showLineNumbers
+# Returns a str
+apiEnvironment = sdk.contextManager.get_api_environment()
+```
+
+
+
+
+## Set cloud auth token
+
+If the SDK was initialized without an authentication token, you can provide or update the token using this function,
+also it is set automatically by [login](accountless.md#login), [register](accountless.md#register-a-new-user), and [refresh-token](account.md#request-a-new-refresh-token).
+
+
+
+
+```kotlin showLineNumbers
+sdk.contextManager().setCloudAuthToken("AUTH_TOKEN")
+```
+
+
+
+
+```java showLineNumbers
+sdk.contextManager().setCloudAuthToken("AUTH_TOKEN");
+```
+
+
+
+
+```swift showLineNumbers
+sdk.contextManager().setCloudAuthToken(token: "AUTH_TOKEN")
+```
+
+
+
+
+```js showLineNumbers
+sdk.contextManager().setCloudAuthToken("AUTH_TOKEN");
+```
+
+
+
+
+```csharp showLineNumbers
+sdk.GetContextManager().SetCloudAuthToken("AUTH_TOKEN");
+```
+
+
+
+
+```python showLineNumbers
+sdk.contextManager.set_cloud_auth_token("AUTH_TOKEN")
+```
+
+
+
+
+## Get cloud auth token
+
+
+
+
+```kotlin showLineNumbers
+val token = sdk.contextManager().getCloudAuthToken()
+```
+
+
+
+
+```java showLineNumbers
+var token = sdk.contextManager().getCloudAuthToken();
+```
+
+
+
+
+```swift showLineNumbers
+let token = sdk.contextManager().getCloudAuthToken()
+```
+
+
+
+
+```js showLineNumbers
+const token = sdk.contextManager().getCloudAuthToken();
+```
+
+
+
+
+```csharp showLineNumbers
+var token = sdk.GetContextManager().GetCloudAuthToken();
+```
+
+
+
+
+```python showLineNumbers
+token = sdk.contextManager.get_cloud_auth_token()
+```
+
+
+
+
+## Is cloud auth token invalid or expired
+
+Checks if the current cloud auth token from the context is invalid, expired
+(we consider it expired if it will expire within the next 24 hours) or invalidated.
+When **checkServerInvalidation** is set to **true**, it also checks if the auth token has been invalidated on the backend.
+This requires a network request. When **checkServerInvalidation** is **false**, this server check is skipped,
+meaning the auth token might be accepted even if it has been invalidated on the server.
+
+
+
+
+```kotlin showLineNumbers
+// Returns a Boolean
+val result = sdk.contextManager().isCloudAuthTokenInvalidOrExpired(true)
+```
+
+
+
+
+```java showLineNumbers
+// Returns a CompletableFuture
+var result = sdk.contextManager().isCloudAuthTokenInvalidOrExpiredAsync(true);
+```
+
+
+
+
+```swift showLineNumbers
+// Returns a Bool asynchronously
+let result = await sdk.contextManager().isCloudAuthTokenInvalidOrExpired(checkServerInvalidation: true)
+```
+
+
+
+
+```js showLineNumbers
+// Returns a Promise
+const result = await sdk.contextManager().isCloudAuthTokenInvalidOrExpired(true);
+```
+
+
+
+
+```csharp showLineNumbers
+// Returns a Task
+var result = await sdk.GetContextManager().IsCloudAuthTokenInvalidOrExpired(checkServerInvalidation: true);
+```
+
+
+
+
+```python showLineNumbers
+# Returns a Future[SimpleNamespace]
+result = await sdk.contextManager.is_cloud_auth_token_invalid_or_expired(True)
+```
+
+
+
+
+## Set cloud refresh token
+
+It is set automatically by [login](accountless.md#login), [register](accountless.md#register-a-new-user),
+and [refresh-tokens](account.md#request-a-new-refresh-token).
+
+
+
+
+```kotlin showLineNumbers
+sdk.contextManager().setCloudRefreshToken("REFRESH_TOKEN")
+```
+
+
+
+
+```java showLineNumbers
+sdk.contextManager().setCloudRefreshToken("REFRESH_TOKEN");
+```
+
+
+
+
+```swift showLineNumbers
+sdk.contextManager().setCloudRefreshToken(token: "REFRESH_TOKEN")
+```
+
+
+
+
+```js showLineNumbers
+sdk.contextManager().setCloudRefreshToken("REFRESH_TOKEN");
+```
+
+
+
+
+```csharp showLineNumbers
+sdk.GetContextManager().SetCloudRefreshToken("REFRESH_TOKEN");
+```
+
+
+
+
+```python showLineNumbers
+sdk.contextManager.set_cloud_refresh_token("REFRESH_TOKEN")
+```
+
+
+
+
+## Get cloud refresh token
+
+
+
+
+```kotlin showLineNumbers
+val token = sdk.contextManager().getCloudRefreshToken()
+```
+
+
+
-import Tabs from '@theme/Tabs';
-import TabItem from '@theme/TabItem';
+```java showLineNumbers
+var token = sdk.contextManager().getCloudRefreshToken();
+```
+
+
+
+
+```swift showLineNumbers
+let token = sdk.contextManager().getCloudRefreshToken()
+```
+
+
+
+
+```js showLineNumbers
+const token = sdk.contextManager().getCloudRefreshToken();
+```
+
+
+
+
+```csharp showLineNumbers
+var token = sdk.GetContextManager().GetCloudRefreshToken();
+```
+
+
+
+
+```python showLineNumbers
+token = sdk.contextManager.get_cloud_refresh_token()
+```
+
+
+
+
+## Set fusion host
+
+Sets the host of the on-premise Fusion server used by the [fusion resource](fusion.md). It can be changed at any
+time, although it is recommended to set it up through the [SdkConfig builder](initialize.md#sdk-config-builder)
+instead.
+
+
+
+
+```kotlin showLineNumbers
+sdk.contextManager().setFusionHost(URI("http://localhost:27700"))
+```
+
+
+
+
+```java showLineNumbers
+sdk.contextManager().setFusionHost(URI.create("http://localhost:27700"));
+```
+
+
+
+
+```swift showLineNumbers
+sdk.contextManager().setFusionHost(host: NSURLComponents(string: "http://localhost:27700")!)
+```
+
+
+
+
+```js showLineNumbers
+sdk.contextManager().setFusionHost("http://localhost:27700");
+```
+
+
+
+
+```csharp showLineNumbers
+sdk.GetContextManager().SetFusionHost("http://localhost:27700");
+```
+
+
+
+
+```python showLineNumbers
+sdk.contextManager.set_fusion_host("http://localhost:27700")
+```
+
+
+
+
+## Get fusion host
+
+Returns the currently configured Fusion host. Defaults to `http://localhost:27700` when it has never been set.
+
+
+
+
+```kotlin showLineNumbers
+// Returns a URI
+val fusionHost = sdk.contextManager().getFusionHost()
+```
+
+
+
+
+```java showLineNumbers
+// Returns a URI
+var fusionHost = sdk.contextManager().getFusionHost();
+```
+
+
+
+
+```swift showLineNumbers
+// Returns an NSURLComponents
+let fusionHost = sdk.contextManager().getFusionHost()
+```
+
+
+
+
+```js showLineNumbers
+// Returns a string
+const fusionHost = sdk.contextManager().getFusionHost();
+```
+
+
+
+
+```csharp showLineNumbers
+// Returns a string
+var fusionHost = sdk.GetContextManager().GetFusionHost();
+```
+
+
+
+
+```python showLineNumbers
+# Returns a str
+fusionHost = sdk.contextManager.get_fusion_host()
+```
+
+
+
+
+## Set fusion auth token
+
+It is set automatically by [fusion login](fusion.md#login).
+
+
+
+
+```kotlin showLineNumbers
+sdk.contextManager().setFusionAuthToken("FUSION_AUTH_TOKEN")
+```
+
+
+
+
+```java showLineNumbers
+sdk.contextManager().setFusionAuthToken("FUSION_AUTH_TOKEN");
+```
+
+
+
+
+```swift showLineNumbers
+sdk.contextManager().setFusionAuthToken(token: "FUSION_AUTH_TOKEN")
+```
+
+
+
+
+```js showLineNumbers
+sdk.contextManager().setFusionAuthToken("FUSION_AUTH_TOKEN");
+```
+
+
+
+
+```csharp showLineNumbers
+sdk.GetContextManager().SetFusionAuthToken("FUSION_AUTH_TOKEN");
+```
+
+
+
+
+```python showLineNumbers
+sdk.contextManager.set_fusion_auth_token("FUSION_AUTH_TOKEN")
+```
+
+
+
+
+## Get fusion auth token
+
+
+
+
+```kotlin showLineNumbers
+val token = sdk.contextManager().getFusionAuthToken()
+```
+
+
+
+
+```java showLineNumbers
+var token = sdk.contextManager().getFusionAuthToken();
+```
+
+
+
+
+```swift showLineNumbers
+let token = sdk.contextManager().getFusionAuthToken()
+```
+
+
+
+
+```js showLineNumbers
+const token = sdk.contextManager().getFusionAuthToken();
+```
+
+
+
+
+```csharp showLineNumbers
+var token = sdk.GetContextManager().GetFusionAuthToken();
+```
+
+
+
+
+```python showLineNumbers
+token = sdk.contextManager.get_fusion_auth_token()
+```
+
+
+
+
+## Set user ID
+
+Sets the user identifier used by the secure [lock operations](lock-operations.md). It is usually set for you by
+[set operation context](#set-operation-context), [register ephemeral key](account.md#register-ephemeral-key)
+and [verify ephemeral key](account.md#verify-ephemeral-key-registration).
+
+
+
+
+```kotlin showLineNumbers
+sdk.contextManager().setUserId(USER_ID)
+```
+
+
+
+
+```java showLineNumbers
+sdk.contextManager().setUserId(USER_ID);
+```
+
+
+
+
+```swift showLineNumbers
+sdk.contextManager().setUserId(userId: USER_ID)
+```
+
+
+
+
+```js showLineNumbers
+sdk.contextManager().setUserId("USER_ID");
+```
+
+
+
+
+```csharp showLineNumbers
+sdk.GetContextManager().SetUserId(USER_ID);
+```
+
+
+
+
+```python showLineNumbers
+sdk.contextManager.set_user_id("USER_ID")
+```
+
+
+
+
+## Get user ID
```kotlin showLineNumbers
-sdk.contextManager().setOperationContext(
- userId = USER_ID,
- certificateChain = USER_CERTIFICATE_CHAIN_LIST,
- keyPair = KEY_PAIR,
- isKeyPairVerified = IS_KEY_PAIR_VERIFIED
-)
+// Returns a UUID
+val userId = sdk.contextManager().getUserId()
```
```java showLineNumbers
-sdk.contextManager().setOperationContext(USER_ID, USER_CERTIFICATE_CHAIN_LIST, KEY_PAIR, IS_KEY_PAIR_VERIFIED);
+// Returns a UUID
+var userId = sdk.contextManager().getUserId();
```
```swift showLineNumbers
-sdk.contextManager().setOperationContext(
- userId: USER_ID,
- certificateChain: USER_CERTIFICATE_CHAIN_LIST,
- publicKey: PUBLIC_KEY,
- privateKey: PRIVATE_KEY,
- isKeyPairVerified: IS_KEY_PAIR_VERIFIED
-)
+// Returns an NSUUID
+let userId = sdk.contextManager().getUserId()
```
```js showLineNumbers
-sdk.contextManager().setOperationContext(
- "USER_ID",
- USER_CERTIFICATE_CHAIN_LIST,
- PUBLIC_KEY,
- PRIVATE_KEY
-);
+// Returns a string
+const userId = sdk.contextManager().getUserId();
```
```csharp showLineNumbers
-sdk.GetContextManager().SetOperationContext(
- userId: USER_ID,
- certificateChain: USER_CERTIFICATE_CHAIN,
- publicKey: PUBLIC_KEY,
- privateKey: PRIVATE_KEY
-);
+// Returns a Guid
+var userId = sdk.GetContextManager().GetUserId();
```
```python showLineNumbers
-sdk.contextManager.set_operation_context(
- "USER_ID",
- "USER_CERTIFICATE_CHAIN_AS_STRING",
- "BASE64_PUBLIC_KEY",
- "BASE64_PRIVATE_KEY"
-)
+# Returns a str
+userId = sdk.contextManager.get_user_id()
```
-## Get Context State
+## Set user email
-Checks the state of the context by verifying that the [auth token is valid](#is-cloud-auth-token-invalid-or-expired),
-the [key pair is valid](#is-key-pair-valid) and [verified](#is-key-pair-verified),
-and the [certificate chain is valid](#is-certificate-chain-invalid-or-expired).
-When **checkServerInvalidation** is set to **true**, it also checks if the auth token has been invalidated on the backend.
-This requires a network request. When **checkServerInvalidation** is **false**, this server check is skipped,
-meaning the auth token might be accepted even if it has been invalidated.
+Sets the email address associated with the context. It is set automatically by
+[login](accountless.md#login) and [registration](accountless.md#register-a-new-user).
```kotlin showLineNumbers
-// Returns a ContextState
-val result = sdk.contextManager().getContextState(true)
+sdk.contextManager().setUserEmail("EMAIL")
```
```java showLineNumbers
-// Returns a CompletableFuture
-var result = sdk.contextManager().getContextStateAsync(true);
+sdk.contextManager().setUserEmail("EMAIL");
```
```swift showLineNumbers
-// Returns a ContextState asynchronously
-let result = await sdk.contextManager().getContextState(checkServerInvalidation: true)
+sdk.contextManager().setUserEmail(email: "EMAIL")
```
```js showLineNumbers
-// Returns a Promise
-const result = await sdk.contextManager().getContextState(true);
+sdk.contextManager().setUserEmail("EMAIL");
```
```csharp showLineNumbers
-// Returns a Task
-var result = await sdk.GetContextManager().GetContextState(checkServerInvalidation: true);
+sdk.GetContextManager().SetUserEmail("EMAIL");
```
```python showLineNumbers
-# Returns a Future[SimpleNamespace]
-result = await sdk.contextManager.get_context_state(True)
+sdk.contextManager.set_user_email("EMAIL")
```
-## Is certificate chain invalid or expired
+## Get user email
-Checks if the current certificate chain from the context is invalid or expired
-(we consider it expired if it will expire within the next 7 days).
+
+
+
+```kotlin showLineNumbers
+val email = sdk.contextManager().getUserEmail()
+```
+
+
+
+
+```java showLineNumbers
+var email = sdk.contextManager().getUserEmail();
+```
+
+
+
+
+```swift showLineNumbers
+let email = sdk.contextManager().getUserEmail()
+```
+
+
+
+
+```js showLineNumbers
+const email = sdk.contextManager().getUserEmail();
+```
+
+
+
+
+```csharp showLineNumbers
+var email = sdk.GetContextManager().GetUserEmail();
+```
+
+
+
+
+```python showLineNumbers
+email = sdk.contextManager.get_user_email()
+```
+
+
+
+
+## Set certificate chain
+
+Sets the certificate chain used to sign the secure [lock operations](lock-operations.md). It is usually set for
+you by [set operation context](#set-operation-context), [register ephemeral key](account.md#register-ephemeral-key)
+and [verify ephemeral key](account.md#verify-ephemeral-key-registration).
+
+:::info
+Only the **first** certificate of the chain is inspected by [is certificate chain invalid or expired](#is-certificate-chain-invalid-or-expired).
+:::
```kotlin showLineNumbers
-val result = sdk.contextManager().isCertificateChainInvalidOrExpired()
+sdk.contextManager().setCertificateChain(USER_CERTIFICATE_CHAIN_LIST)
```
```java showLineNumbers
-var result = sdk.contextManager().isCertificateChainInvalidOrExpired();
+sdk.contextManager().setCertificateChain(USER_CERTIFICATE_CHAIN_LIST);
```
```swift showLineNumbers
-let result = sdk.contextManager().isCertificateChainInvalidOrExpired()
+sdk.contextManager().setCertificateChain(certificateChain: USER_CERTIFICATE_CHAIN_LIST)
```
```js showLineNumbers
-const result = sdk.contextManager().isCertificateChainInvalidOrExpired();
+sdk.contextManager().setCertificateChain(USER_CERTIFICATE_CHAIN_LIST);
```
```csharp showLineNumbers
-var result = sdk.GetContextManager().IsCertificateChainInvalidOrExpired();
+// Not implemented yet
```
```python showLineNumbers
-result = sdk.contextManager.is_certificate_chain_invalid_or_expired()
+// Not implemented yet
```
-## Is key pair valid
+## Get certificate chain
-Checks if the current key pair from the context is valid.
+Returns the stored certificate chain, or **null** when none has been set.
```kotlin showLineNumbers
-val result = sdk.contextManager().isKeyPairValid()
+// Returns a List
+val certificateChain = sdk.contextManager().getCertificateChain()
```
```java showLineNumbers
-var result = sdk.contextManager().isKeyPairValid();
+// Returns a List
+var certificateChain = sdk.contextManager().getCertificateChain();
```
```swift showLineNumbers
-let result = sdk.contextManager().isKeyPairValid()
+// Returns a [String]
+let certificateChain = sdk.contextManager().getCertificateChain()
```
```js showLineNumbers
-const result = sdk.contextManager().isKeyPairValid();
+// Returns a string[]
+const certificateChain = sdk.contextManager().getCertificateChain();
```
```csharp showLineNumbers
-var result = sdk.GetContextManager().IsKeyPairValid();
+// Not implemented yet
```
```python showLineNumbers
-result = sdk.contextManager.is_key_pair_valid()
+// Not implemented yet
```
-## Is key pair verified
+## Is certificate chain invalid or expired
-Checks if the current key pair from the context has been verified.
+Checks if the current certificate chain from the context is invalid or expired
+(we consider it expired if it will expire within the next 7 days).
```kotlin showLineNumbers
-val result = sdk.contextManager().isKeyPairVerified()
+val result = sdk.contextManager().isCertificateChainInvalidOrExpired()
```
```java showLineNumbers
-var result = sdk.contextManager().isKeyPairVerified();
+var result = sdk.contextManager().isCertificateChainInvalidOrExpired();
```
```swift showLineNumbers
-let result = sdk.contextManager().isKeyPairVerified()
+let result = sdk.contextManager().isCertificateChainInvalidOrExpired()
```
```js showLineNumbers
-const result = sdk.contextManager().isKeyPairVerified();
+const result = sdk.contextManager().isCertificateChainInvalidOrExpired();
```
```csharp showLineNumbers
-var result = sdk.GetContextManager().IsKeyPairVerified();
+var result = sdk.GetContextManager().IsCertificateChainInvalidOrExpired();
```
```python showLineNumbers
-result = sdk.contextManager.is_key_pair_verified()
+result = sdk.contextManager.is_certificate_chain_invalid_or_expired()
```
-## Set cloud auth token
+## Set key pair
-If the SDK was initialized without an authentication token, you can provide or update the token using this function.
+Sets the key pair used to sign the secure [lock operations](lock-operations.md). It is usually set for you by
+[set operation context](#set-operation-context), [register ephemeral key](account.md#register-ephemeral-key)
+and [verify ephemeral key](account.md#verify-ephemeral-key-registration).
+
+:::info
+Setting a new key pair does **not** mark it as verified. Use [set key pair verified](#set-key-pair-verified),
+or register it through [register ephemeral key](account.md#register-ephemeral-key) plus and [verify ephemeral key](account.md#verify-ephemeral-key-registration).
+:::
```kotlin showLineNumbers
-sdk.contextManager().setCloudAuthToken("AUTH_TOKEN")
+sdk.contextManager().setKeyPair(KEY_PAIR)
```
```java showLineNumbers
-sdk.contextManager().setCloudAuthToken("AUTH_TOKEN");
+sdk.contextManager().setKeyPair(KEY_PAIR);
```
```swift showLineNumbers
-sdk.contextManager().setCloudAuthToken(token: "AUTH_TOKEN")
+sdk.contextManager().setKeyPair(
+ publicKey: PUBLIC_KEY,
+ privateKey: PRIVATE_KEY
+)
```
```js showLineNumbers
-sdk.contextManager().setCloudAuthToken("AUTH_TOKEN");
+sdk.contextManager().setKeyPair(PUBLIC_KEY, PRIVATE_KEY);
```
```csharp showLineNumbers
-sdk.GetContextManager().SetCloudAuthToken("AUTH_TOKEN");
+// Not implemented yet
```
```python showLineNumbers
-sdk.contextManager.set_cloud_auth_token("AUTH_TOKEN")
+// Not implemented yet
```
-## Get cloud auth token
+## Get key pair
+
+Returns the stored key pair, or **null** when either the public or the private key is missing.
```kotlin showLineNumbers
-val token = sdk.contextManager().getCloudAuthToken()
+// Returns a KeyPair
+val keyPair = sdk.contextManager().getKeyPair()
```
```java showLineNumbers
-var token = sdk.contextManager().getCloudAuthToken();
+// Returns a KeyPair
+var keyPair = sdk.contextManager().getKeyPair();
```
```swift showLineNumbers
-let token = sdk.contextManager().getCloudAuthToken()
+// Returns a Crypto.KeyPair
+let keyPair = sdk.contextManager().getKeyPair()
```
```js showLineNumbers
-const token = sdk.contextManager().getCloudAuthToken();
+// Returns a Crypto.KeyPair
+const keyPair = sdk.contextManager().getKeyPair();
```
```csharp showLineNumbers
-var token = sdk.GetContextManager().GetCloudAuthToken();
+// Not implemented yet
```
```python showLineNumbers
-token = sdk.contextManager.get_cloud_auth_token()
+// Not implemented yet
```
-## Is cloud auth token invalid or expired
+## Set key pair verified
-Checks if the current cloud auth token from the context is invalid, expired
-(we consider it expired if it will expire within the next 24 hours) or invalidated.
-When **checkServerInvalidation** is set to **true**, it also checks if the auth token has been invalidated on the backend.
-This requires a network request. When **checkServerInvalidation** is **false**, this server check is skipped,
-meaning the auth token might be accepted even if it has been invalidated on the server.
+Marks a public key as verified, meaning it has successfully completed
+[two-factor verification](account.md#verify-ephemeral-key-registration). Pass **null** to clear the verification.
+
+:::info
+[Is key pair verified](#is-key-pair-verified) compares the value stored here against the current public key,
+so setting a key pair that does not match clears the verified state in practice.
+:::
```kotlin showLineNumbers
-// Returns a Boolean
-val result = sdk.contextManager().isCloudAuthTokenInvalidOrExpired(true)
+sdk.contextManager().setKeyPairVerified(PUBLIC_KEY)
```
```java showLineNumbers
-// Returns a CompletableFuture
-var result = sdk.contextManager().isCloudAuthTokenInvalidOrExpiredAsync(true);
+sdk.contextManager().setKeyPairVerified(PUBLIC_KEY);
```
```swift showLineNumbers
-// Returns a Bool asynchronously
-let result = await sdk.contextManager().isCloudAuthTokenInvalidOrExpired(checkServerInvalidation: true)
+sdk.contextManager().setKeyPairVerified(publicKey: PUBLIC_KEY)
```
```js showLineNumbers
-// Returns a Promise
-const result = await sdk.contextManager().isCloudAuthTokenInvalidOrExpired(true);
+sdk.contextManager().setKeyPairVerified(PUBLIC_KEY);
```
```csharp showLineNumbers
-// Returns a Task
-var result = await sdk.GetContextManager().IsCloudAuthTokenInvalidOrExpired(checkServerInvalidation: true);
+// Not implemented yet
```
```python showLineNumbers
-# Returns a Future[SimpleNamespace]
-result = await sdk.contextManager.is_cloud_auth_token_invalid_or_expired(True)
+// Not implemented yet
```
-## Set cloud refresh token
+## Is key pair verified
+
+Checks if the current key pair from the context has been verified.
```kotlin showLineNumbers
-sdk.contextManager().setCloudRefreshToken("REFRESH_TOKEN")
+val result = sdk.contextManager().isKeyPairVerified()
```
```java showLineNumbers
-sdk.contextManager().setCloudRefreshToken("REFRESH_TOKEN");
+var result = sdk.contextManager().isKeyPairVerified();
```
```swift showLineNumbers
-sdk.contextManager().setCloudRefreshToken(token: "REFRESH_TOKEN")
+let result = sdk.contextManager().isKeyPairVerified()
```
```js showLineNumbers
-sdk.contextManager().setCloudRefreshToken("REFRESH_TOKEN");
+const result = sdk.contextManager().isKeyPairVerified();
```
```csharp showLineNumbers
-sdk.GetContextManager().SetCloudRefreshToken("REFRESH_TOKEN");
+var result = sdk.GetContextManager().IsKeyPairVerified();
```
```python showLineNumbers
-sdk.contextManager.set_cloud_refresh_token("REFRESH_TOKEN")
+result = sdk.contextManager.is_key_pair_verified()
```
-## Get cloud refresh token
+## Is key pair valid
+
+Checks if the current key pair from the context is valid.
```kotlin showLineNumbers
-val token = sdk.contextManager().getCloudRefreshToken()
+val result = sdk.contextManager().isKeyPairValid()
```
```java showLineNumbers
-var token = sdk.contextManager().getCloudRefreshToken();
+var result = sdk.contextManager().isKeyPairValid();
```
```swift showLineNumbers
-let token = sdk.contextManager().getCloudRefreshToken()
+let result = sdk.contextManager().isKeyPairValid()
```
```js showLineNumbers
-const token = sdk.contextManager().getCloudRefreshToken();
+const result = sdk.contextManager().isKeyPairValid();
```
```csharp showLineNumbers
-var token = sdk.GetContextManager().GetCloudRefreshToken();
+var result = sdk.GetContextManager().IsKeyPairValid();
```
```python showLineNumbers
-token = sdk.contextManager.get_cloud_refresh_token()
+result = sdk.contextManager.is_key_pair_valid()
```
-## Set fusion auth token
+## Set operation context
+
+import Tabs from '@theme/Tabs';
+import TabItem from '@theme/TabItem';
```kotlin showLineNumbers
-sdk.contextManager().setFusionAuthToken("FUSION_AUTH_TOKEN")
+sdk.contextManager().setOperationContext(
+ userId = USER_ID,
+ certificateChain = USER_CERTIFICATE_CHAIN_LIST,
+ keyPair = KEY_PAIR,
+ isKeyPairVerified = IS_KEY_PAIR_VERIFIED
+)
```
```java showLineNumbers
-sdk.contextManager().setFusionAuthToken("FUSION_AUTH_TOKEN");
+sdk.contextManager().setOperationContext(USER_ID, USER_CERTIFICATE_CHAIN_LIST, KEY_PAIR, IS_KEY_PAIR_VERIFIED);
```
```swift showLineNumbers
-sdk.contextManager().setFusionAuthToken(token: "FUSION_AUTH_TOKEN")
+sdk.contextManager().setOperationContext(
+ userId: USER_ID,
+ certificateChain: USER_CERTIFICATE_CHAIN_LIST,
+ publicKey: PUBLIC_KEY,
+ privateKey: PRIVATE_KEY,
+ isKeyPairVerified: IS_KEY_PAIR_VERIFIED
+)
```
```js showLineNumbers
-sdk.contextManager().setFusionAuthToken("FUSION_AUTH_TOKEN");
+sdk.contextManager().setOperationContext(
+ "USER_ID",
+ USER_CERTIFICATE_CHAIN_LIST,
+ PUBLIC_KEY,
+ PRIVATE_KEY
+);
```
```csharp showLineNumbers
-sdk.GetContextManager().SetFusionAuthToken("FUSION_AUTH_TOKEN");
+sdk.GetContextManager().SetOperationContext(
+ userId: USER_ID,
+ certificateChain: USER_CERTIFICATE_CHAIN,
+ publicKey: PUBLIC_KEY,
+ privateKey: PRIVATE_KEY
+);
```
```python showLineNumbers
-sdk.contextManager.set_fusion_auth_token("FUSION_AUTH_TOKEN")
+sdk.contextManager.set_operation_context(
+ "USER_ID",
+ "USER_CERTIFICATE_CHAIN_AS_STRING",
+ "BASE64_PUBLIC_KEY",
+ "BASE64_PRIVATE_KEY"
+)
```
-## Get fusion auth token
+## Get Context State
+
+Checks the state of the context by verifying that the [auth token is valid](#is-cloud-auth-token-invalid-or-expired),
+the [key pair is valid](#is-key-pair-valid) and [verified](#is-key-pair-verified),
+and the [certificate chain is valid](#is-certificate-chain-invalid-or-expired).
+When **checkServerInvalidation** is set to **true**, it also checks if the auth token has been invalidated on the backend.
+This requires a network request. When **checkServerInvalidation** is **false**, this server check is skipped,
+meaning the auth token might be accepted even if it has been invalidated.
```kotlin showLineNumbers
-val token = sdk.contextManager().getFusionAuthToken()
+// Returns a ContextState
+val result = sdk.contextManager().getContextState(true)
```
```java showLineNumbers
-var token = sdk.contextManager().getFusionAuthToken();
+// Returns a CompletableFuture
+var result = sdk.contextManager().getContextStateAsync(true);
```
```swift showLineNumbers
-let token = sdk.contextManager().getFusionAuthToken()
+// Returns a ContextState asynchronously
+let result = await sdk.contextManager().getContextState(checkServerInvalidation: true)
```
```js showLineNumbers
-const token = sdk.contextManager().getFusionAuthToken();
+// Returns a Promise
+const result = await sdk.contextManager().getContextState(true);
```
```csharp showLineNumbers
-var token = sdk.GetContextManager().GetFusionAuthToken();
+// Returns a Task
+var result = await sdk.GetContextManager().GetContextState(checkServerInvalidation: true);
```
```python showLineNumbers
-token = sdk.contextManager.get_fusion_auth_token()
+# Returns a Future[SimpleNamespace]
+result = await sdk.contextManager.get_context_state(True)
```
diff --git a/docs/kotlin-multiplatform-sdk/crypto.md b/docs/kotlin-multiplatform-sdk/crypto.md
index 74d740e0..93753788 100644
--- a/docs/kotlin-multiplatform-sdk/crypto.md
+++ b/docs/kotlin-multiplatform-sdk/crypto.md
@@ -1,7 +1,23 @@
# Crypto
+The crypto manager exposes the cryptographic primitives the SDK uses for
+[ephemeral key registration](account.md#register-ephemeral-key) and for signing
+[lock operations](lock-operations.md). All key pairs are **Ed25519**.
+
+Each platform uses its own crypto provider and its own native key encoding:
+
+| Platform | Provider |
+|:---------------------:|:-------------------:|
+| JVM | Java Security API |
+| Android | Bouncy Castle |
+| iOS / macOS / watchOS | Apple CryptoKit |
+| JS / Broswer / Node | Libsodium |
+| C# / Python | Libsodium |
+
## Generate a key pair
+Generates a brand-new Ed25519 key pair. The key pair is **not** stored automatically.
+
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
diff --git a/docs/kotlin-multiplatform-sdk/initialize.md b/docs/kotlin-multiplatform-sdk/initialize.md
index e18f7013..6caba247 100644
--- a/docs/kotlin-multiplatform-sdk/initialize.md
+++ b/docs/kotlin-multiplatform-sdk/initialize.md
@@ -23,13 +23,14 @@ If you initialize the SDK without a cloud auth token, you will need to either pr
By default, the SDK stores the context information on its own, as shown in the following table:
-| Platform | Storage |
-|:---------------------:|:------------------------------:|
-| Android | `EncryptedSharedPreferences` |
-| JVM | `Memory` |
-| iOS / macOS / watchOS | `Keychain` |
-| JS / Node | `LocalStorage` |
-| C# / Python | `Memory` |
+| Platform | Storage |
+|:---------------------:|:----------------------------:|
+| Android | `EncryptedSharedPreferences` |
+| JVM | `Memory` |
+| iOS / macOS / watchOS | `Keychain` |
+| JS Browser | `LocalStorage` |
+| JS Node | `Memory` |
+| C# / Python | `Memory` |
:::info
To override the default secure storage, you must implement the `SecureStorage` interface and pass the class through the `setSecureStorageOverride` function from `SdkConfig` builder.
@@ -50,6 +51,10 @@ val sdkConfig = SdkConfig.Builder()
val sdk = KDoordeckFactory.initialize(sdkConfig)
```
+:::info
+You should also call `sdk.release()` at the end of your application's lifecycle to release the SDK resources.
+:::
+
@@ -60,6 +65,10 @@ var sdkConfig = SdkConfig.Builder()
var sdk = KDoordeckFactory.INSTANCE.initializeAsync(sdkConfig);
```
+:::info
+You should also call `sdk.release();` at the end of your application's lifecycle to release the SDK resources.
+:::
+
@@ -70,6 +79,10 @@ let sdkConfig = SdkConfig.Builder()
let sdk = await KDoordeckFactory().initialize(sdkConfig: sdkConfig)
```
+:::info
+You should also call `sdk.release()` at the end of your application's lifecycle to release the SDK resources.
+:::
+
@@ -83,6 +96,10 @@ const sdk = await com.doordeck.multiplatform.sdk.KDoordeckFactory.initialize(
);
```
+:::info
+You should also call `sdk.release()` at the end of your application's lifecycle to release the SDK resources.
+:::
+
@@ -101,5 +118,9 @@ You should also call `sdk.Release();` at the end of your application’s lifecyc
sdk = doordeck_headless_sdk.InitializeSdk(cloud_auth_token="AUTH_TOKEN")
```
+:::info
+You should also call `sdk.release()` at the end of your application's lifecycle to release the SDK resources.
+:::
+