> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portalhq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Feature Flags

> Feature flags allow you to enable or disable specific features in the Portal SDK. This provides flexibility in customizing the behavior of the SDK for your application.

### Overview

The `FeatureFlags` struct is used to configure feature flags when initializing the Portal SDK. Each flag corresponds to a specific feature or behavior that can be toggled on or off.

#### Example Usage:

```swift theme={null}
import PortalSwift

// Initialize Portal with custom feature flags
let portal = try Portal(
  "CLIENT_API_KEY_OR_CLIENT_SESSION_TOKEN",
  featureFlags: FeatureFlags(
    useEnclaveMPCApi: true
  )
)
```

***

### Available Feature Flags

Below is a list of available feature flags and their functionality.

#### 1. `useEnclaveMPCApi`

* **Type**: `Bool?`
* **Default**: `nil` (disabled)
* **Description**: Enables the use of the **Enclave MPC API** for signing transactions. When enabled, MPC operations are executed server-side in a secure AWS Nitro Enclave, ensuring consistent and faster signing times.

**How It Works**

Executing MPC operations on client devices can lead to inconsistent signing times due to variations in device CPU performance. By enabling the `useEnclaveMPCApi` flag, the client key share is transmitted to a **Trusted Execution Environment (TEE)** hosted in an AWS Nitro Enclave. This ensures:

1. **Encrypted Memory**: All data processed in the enclave is encrypted and inaccessible to anyone, including Portal employees.
2. **Verified Execution**: Users can cryptographically verify that their request was handled in a secure enclave using signed measurements.

**Example:**

```swift theme={null}
import PortalSwift

// Initialize Portal with the Enclave MPC API enabled
let portal = try Portal(
  "CLIENT_API_KEY_OR_CLIENT_SESSION_TOKEN",
  featureFlags: FeatureFlags(
    useEnclaveMPCApi: true
  )
)
```

By setting `useEnclaveMPCApi` to `true`, the Portal instance will use the Enclave MPC API for signing transactions, ensuring faster computation and consistent performance across client devices.

***

#### 2. `usePreGeneratedWallet`

* **Type**: `Bool?`
* **Default**: `nil` (disabled)
* **Description**: When enabled, `portal.createWallet()` attempts to claim a pre-generated wallet share instead of running the standard interactive MPC generation. This can make wallet creation faster. You do not need to change how you call `createWallet`.

**How It Works**

Normally, `createWallet` runs the MPC key generation (DKG) protocol on the device, interactively with the MPC servers, at the moment it is called. With this flag enabled, the SDK asks the Enclave MPC API for the shares instead, and the enclave serves them from a pool it generated ahead of time.

There are two independent fallbacks, and they happen at different layers:

* **Enclave-side fallback—invisible to the SDK.** If the pool is empty or a share can't be claimed, the enclave generates the shares on demand and returns them in a normal `200 OK` response. The SDK can't tell the two responses apart, and it doesn't need to: the resulting wallet is the same either way, and generation still happens server-side rather than on the device.
* **SDK-side fallback—only on an HTTP 5xx.** If the enclave responds with a 5xx, the SDK falls back to running the standard on-device DKG protocol. The fallback is transparent, and `createWallet` returns or throws exactly as it would through the standard flow.

Every other failure is thrown as-is, since retrying on the device wouldn't resolve it.

| Case                             | Behavior                                                                                                                                                                                                                                       |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Flag disabled (default)**      | `createWallet` runs the standard on-device DKG protocol, exactly as it does today.                                                                                                                                                             |
| **Flag enabled, share claimed**  | The enclave returns a pre-generated share and `createWallet` completes faster than the standard flow.                                                                                                                                          |
| **Pool temporarily unavailable** | The enclave generates the shares on demand and returns a successful response. The SDK does *not* fall back to the on-device flow, and your app sees a normal success.                                                                          |
| **Enclave returns an HTTP 5xx**  | The SDK falls back to the standard on-device DKG protocol and completes wallet creation that way.                                                                                                                                              |
| **Client already has a wallet**  | The enclave responds `400`—`Not eligible to claim a pre-generated wallet`, or `Wallet already exists` when it's caught while finalizing the claim—and `createWallet` throws. This is the most common failure to expect with this flag enabled. |
| **Any other failure**            | Other 4xx client errors, an invalid API key, a network failure, or a share that fails to decode are thrown as-is.                                                                                                                              |

Claiming a share does not change the security model: shares are still split between the user's device and Portal, and the pre-generated shares are produced in the same Trusted Execution Environment described in the `useEnclaveMPCApi` section above.

**When to enable**

Enable `usePreGeneratedWallet` when you want faster wallet creation without changing your integration. It helps most on older devices, where running the DKG protocol on the handset is slowest and least consistent. The resulting wallet is identical to one created through the standard flow.

**Limitations**

* This is a performance optimization only; it doesn't change the API surface, the resulting wallet, or how backup and recovery work.
* The SDK only retries on the device when the enclave returns an HTTP 5xx. Other errors, including network failures, propagate normally—so a misconfigured API key, or calling `createWallet` for a client that already has a wallet, produces a failed wallet creation rather than a slow one. Keep your existing error handling around `createWallet`.
* Because the enclave generates on demand when the pool is empty, enabling this flag doesn't guarantee the share came from the pool—only that wallet creation didn't run on the device.

**Example:**

```swift theme={null}
import PortalSwift

// Initialize Portal with pre-generated wallets enabled
let portal = try Portal(
  "CLIENT_API_KEY_OR_CLIENT_SESSION_TOKEN",
  featureFlags: FeatureFlags(
    usePreGeneratedWallet: true
  )
)

do {
  let addresses = try await portal.createWallet()

  print("My Portal EVM address: \(addresses.ethereum)")
  print("My Portal Solana address: \(addresses.solana)")
} catch {
  // The SDK already retried on the device if the enclave returned a 5xx, so
  // reaching this point means the failure was not retryable—most commonly
  // because this client already has a wallet.
  print("Failed to create wallet: \(error)")
}
```

Every parameter on `FeatureFlags` is optional and defaulted, so you can enable `usePreGeneratedWallet` on its own as shown above, or alongside any other flag.

**Types**

Claiming a share calls the Enclave MPC API at `POST https://{enclaveMPCHost}/v1/generate`, where `enclaveMPCHost` is configurable and defaults to `mpc-client.portalhq.io`. The response type is public so you can build mocks and tests against it—most integrations never reference it directly, since `createWallet` handles the response for you.

```swift theme={null}
// A single curve's share. `share` is the base64-encoded serialized MPC share.
public struct GenerateApiCurveShare: Decodable {
  public let share: String
  public let id: String
}

public struct GenerateApiResponse: Decodable {
  public let secp256k1: GenerateApiCurveShare
  public let ed25519: GenerateApiCurveShare

  // The enclave returns uppercase curve names on the wire.
  enum CodingKeys: String, CodingKey {
    case secp256k1 = "SECP256K1"
    case ed25519 = "ED25519"
  }
}
```
