# Passkey

The Swift Passkey Module provides secure and streamlined user authentication and registration using modern passkey technology. It offers methods to check if a user exists, to authenticate users, and to register new users. Below is an overview of the available methods and an example of how to construct a PasskeyClientImpl.

***

#### Constructing PasskeyClientImpl

The **PasskeyClientImpl** class is a concrete implementation of the PasskeyClient protocol. It integrates with a network service and a passkey authentication service to perform user checks, authentication, and registration.

**Example:**

```swift
// Obtain a reference to an ASPresentationAnchor (e.g., your application's key window or a scene window)
let window: ASPresentationAnchor = /* your ASPresentationAnchor instance */

// Your API key and authentication server address
let apiKey = "YOUR_API_KEY"
let authServerAddress = "https://your-auth-server.com"

// Create an instance of PasskeyClientImpl
let passkeyClient: PasskeyClient = PasskeyClientImpl(window: window, apiKey: apiKey, authServerAddress: authServerAddress)

// Now you can use passkeyClient to call isUserExist, authenticate, and register methods.
```

#### 1. isUserExist

The **isUserExist()** method checks whether a user with the specified username exists in the system. It makes a network call to verify the user’s existence and returns the result asynchronously via a completion handler.

**Example:**

```swift
// Check if the user "john_doe" exists
passkeyClient.isUserExist(username: "john_doe") { result in
    switch result {
    case .success(let exists):
        print("User exists: \(exists)")
    case .failure(let error):
        print("Error checking user existence: \(error)")
    }
}
```

***

#### 2. authenticate

The **authenticate()** method initiates the passkey authentication process for a user. It retrieves authentication options from the network, starts the authentication flow via the passkey service, and verifies the response. The result is returned asynchronously.

**Example:**

```swift
@available(iOS 16.0, *)
func authenticateUser() {
    let cancellable = try? passkeyClient?
        .authenticate(username: "example_user")
        .sink(receiveCompletion: { completion in
            switch completion {
            case .finished:
                break
            case .failure(let error):
                print("Error during authentication: \(error)")
            }
        }, receiveValue: { authResponse in
            // Handle successful authentication
            // e.g., store the access token: authResponse.accessToken
            print("Authentication succeeded: \(authResponse)")
        })
}
```

***

#### 3. register

The **register()** method starts the passkey-based registration process for a new user. It obtains registration options from the network, initiates the registration flow via the passkey service, and verifies the registration response. The result is returned asynchronously via a completion handler.

**Example:**

```swift
// Register a new user "john_doe"
import Combine

@available(iOS 16.0, *)
func registerUser() {
    let cancellable = try? passkeyClient?
        .register(username: "new_user")
        .sink(receiveCompletion: { completion in
            switch completion {
            case .finished:
                break
            case .failure(let error):
                print("Error during registration: \(error)")
            }
        }, receiveValue: { registerResponse in
            // Handle successful registration
            // e.g., store user ID: registerResponse.userId
            print("Registration succeeded: \(registerResponse)")
        })
}
```
