> ## Documentation Index
> Fetch the complete documentation index at: https://jdev-e8db0569.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Architecture

> How seon_orchestration_flutter bridges Flutter to the native SEON SDKs.

## Overview

seon\_orchestration\_flutter is built as a Flutter plugin using MethodChannel to bridge Dart to the native SEON Orchestration SDKs on iOS and Android.

## Architecture Layers

### Dart Layer

The Dart layer provides the public API, types, and MethodChannel communication.

**Key files:**

* `lib/src/seon_orchestration.dart` — Public API with static methods wrapping MethodChannel calls
* `lib/src/types.dart` — Dart classes and enums (SeonConfig, SeonVerificationResult, SeonVerificationStatus, SeonErrorCode, SeonException)
* `lib/seon_orchestration_flutter.dart` — Barrel export file

The MethodChannel is defined with the name `seon_orchestration`:

```dart theme={null}
class SeonOrchestration {
  @visibleForTesting
  static MethodChannel channel = const MethodChannel('seon_orchestration');

  static Future<void> initialize(SeonConfig config) async {
    try {
      await channel.invokeMethod<void>('initialize', {
        'baseUrl': config.baseUrl,
        'token': config.token,
        if (config.language != null) 'language': config.language,
        if (config.themeJson != null) 'theme': config.themeJson,
      });
    } on PlatformException catch (e) {
      throw SeonException(
        code: SeonErrorCode.fromString(e.code),
        rawCode: e.code,
        message: e.message ?? 'Unknown initialization error',
      );
    }
  }

  static Future<SeonVerificationResult> startVerification() async { ... }

  static Future<void> dispose() async { ... }
}
```

The channel is exposed with `@visibleForTesting` so tests can swap in a mock channel without needing a platform interface package.

### iOS Implementation

The iOS implementation uses Swift with a plugin registrar pattern.

**Key files:**

* `ios/Classes/SeonOrchestrationPlugin.swift` — Plugin registrar, receives MethodChannel calls
* `ios/Classes/SeonOrchestrationImpl.swift` — Swift singleton with actual SDK integration

**How it works:**

1. `SeonOrchestrationPlugin` registers as a MethodChannel handler
2. Incoming method calls are dispatched to `SeonOrchestrationImpl`
3. `SeonOrchestrationImpl` manages SDK initialization and verification flow
4. Results are returned via the FlutterResult callback

The Swift class `SeonOrchestrationImpl` handles:

* SDK initialization with configuration
* Managing the `UINavigationController` for the verification flow
* Implementing `SEONOrchSDKServiceDelegate` to receive callbacks
* Bridging delegate callbacks to the stored FlutterResult

### Android Implementation

The Android implementation is written in Kotlin and uses a proxy Activity pattern.

**Key files:**

* `android/.../SeonOrchestrationPlugin.kt` — FlutterPlugin + ActivityAware implementation
* `android/.../SeonVerificationActivity.kt` — Transparent proxy Activity

**How it works:**

1. `startVerification` is called from Dart via MethodChannel
2. Plugin stores the MethodChannel result and launches the proxy Activity
3. Proxy Activity registers an `ActivityResultLauncher` and starts SEON verification
4. When complete, the Activity resolves the stored result and finishes itself

**Why a proxy Activity?**

* The SEON SDK requires an Activity to launch its flow
* `ActivityResultLauncher` must be registered before the Activity reaches STARTED lifecycle state
* The proxy Activity provides a clean lifecycle boundary
* It uses a transparent theme (`Theme.Translucent.NoTitleBar`) so users don't see it

```kotlin theme={null}
class SeonVerificationActivity : ComponentActivity() {
    private val verificationLauncher = registerForActivityResult(StartActivityForResult()) { result ->
        resolveResult(result.resultCode, result.data)
        finish()
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // If restored after process death, pendingResult is gone — finish immediately.
        if (savedInstanceState != null && pendingResult == null) {
            finish()
            return
        }

        OrchestrationService.instance.startVerificationFlow(verificationLauncher, applicationContext)
    }
}
```

## Data Flow

### Initialization Flow

```
Dart                     MethodChannel            Native
  |                          |                       |
  | initialize(config)       |                       |
  |------------------------->|                       |
  |                          | invokeMethod           |
  |                          |----------------------->|
  |                          |                       | Initialize SDK
  |                          |                       | Store config
  |                          |    FlutterResult       |
  |                          |<-----------------------|
  |     Future completes     |                       |
  |<-------------------------|                       |
```

### Verification Flow

```
Dart                     MethodChannel            Native                  SEON SDK
  |                          |                       |                         |
  | startVerification()      |                       |                         |
  |------------------------->|                       |                         |
  |                          | invokeMethod           |                         |
  |                          |----------------------->|                         |
  |                          |                       | Store result callback    |
  |                          |                       | Launch Activity/Present  |
  |                          |                       |------------------------>|
  |                          |                       |                         | User interaction
  |                          |                       |    Delegate callbacks    |
  |                          |                       |<------------------------|
  |                          |    FlutterResult       |                         |
  |                          |<-----------------------|                         |
  |     Result received      |                       |                         |
  |<-------------------------|                       |                         |
```

## Error Handling

Errors are propagated through PlatformException:

1. Native code catches exceptions
2. Returns error via FlutterResult with error code and message
3. Dart receives PlatformException
4. Plugin wraps it as `SeonException` with a typed `SeonErrorCode` enum and the raw platform string

Error codes are defined consistently across platforms to provide a unified error API. The `SeonErrorCode.fromString()` method maps raw platform strings to enum values, with `unknown` as a fallback.

## Thread Safety

* **iOS**: All SDK calls are explicitly dispatched to the main thread
* **Android**: Activity lifecycle ensures operations run on the UI thread
* **MethodChannel**: Flutter handles thread marshalling automatically

## Performance Considerations

* **Lazy initialization**: SDK is not initialized until `initialize()` is called
* **Single instance**: Only one verification can run at a time
* **Transparent UI**: Android proxy Activity uses transparent theme to avoid UI flicker
* **Efficient bridging**: MethodChannel uses binary message passing with minimal overhead
