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

# Providers

> Flutter providers and scopes for the Flutter SDK reference for Crossmint wallets

The Flutter SDK provides widget-based providers and scopes for integrating wallet functionality into your widget tree. These are optional — the SDK is headless-first and all features can be used directly via [controllers](/sdk-reference/wallets/flutter/controllers).

1. `CrossmintWalletProvider` — All-in-one provider (recommended)
2. `CrossmintClientScope` — Low-level client scope
3. `CrossmintAuthScope` — Low-level auth scope
4. `CrossmintWalletScope` — Low-level wallet scope

***

## CrossmintWalletProvider

All-in-one provider that initializes the client, auth, and wallet controller. Handles session restoration, OAuth callback routing, and OTP prompt display automatically. This is the recommended entry point for widget-based apps.

### Props

<ResponseField name="config" type="CrossmintWalletProviderConfig" required>
  The configuration this provider was built with.

  <Expandable title="properties">
    <ResponseField name="clientConfig" type="CrossmintClientConfig?">
      Config used to build a new \[CrossmintClient]. Mutually exclusive with \[dependencies].

      <Expandable title="properties">
        <ResponseField name="authStorage" type="CrossmintAuthStorage?">
          Custom session / token store. When null, the SDK uses `FlutterSecureStorage` under the hood.
        </ResponseField>

        <ResponseField name="logger" type="CrossmintLogger?">
          Custom logger sink. When null, the SDK uses a no-op logger in release and a `debugPrint`-backed logger in debug.
        </ResponseField>

        <ResponseField name="refreshRoute" type="Uri?">
          Optional custom server endpoint for token refresh.
        </ResponseField>

        <ResponseField name="logoutRoute" type="Uri?">
          Optional custom server endpoint for logout.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="walletControllerConfig" type="CrossmintWalletControllerConfig">
      Config for the wallet controller the provider creates.

      <Expandable title="properties">
        <ResponseField name="createOnLogin" type="CrossmintCreateOnLoginConfig?">
          When set, the controller automatically creates (or loads) a wallet on the given chain once the user is authenticated. Fill `recovery` with the recovery signer config (e.g. `CrossmintEmailSignerConfig()`).
        </ResponseField>

        <ResponseField name="showOtpSignerPrompt" type="bool">
          Whether the SDK should surface the default OTP prompt automatically. Set to `false` to drive OTP UI yourself by listening to \[CrossmintWalletController.otp].
        </ResponseField>

        <ResponseField name="callbacks" type="CrossmintWalletLifecycleCallbacks?">
          Optional lifecycle hooks — see \[CrossmintWalletLifecycleCallbacks].
        </ResponseField>

        <ResponseField name="deviceSignerKeyStorage" type="DeviceSignerKeyStorage?">
          Storage adapter used to persist device-signer keys. Defaults to a secure-enclave / keystore-backed implementation on device.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="dependencies" type="CrossmintWalletProviderDependencies?">
      Pre-built dependencies — use this when you want to share a client or controller between mount points. Mutually exclusive with \[clientConfig].

      <Expandable title="properties">
        <ResponseField name="client" type="CrossmintClient" required>
          An already-initialized client. The provider will not dispose this unless \[CrossmintWalletProviderConfig.disposeInjectedDependencies] is `true`.
        </ResponseField>

        <ResponseField name="walletController" type="CrossmintWalletController" required>
          An already-built wallet controller bound to \[client].
        </ResponseField>

        <ResponseField name="authCallbackRouter" type="CrossmintAuthCallbackRouter?">
          Optional pre-built callback router for OAuth deep links.
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="disposeInjectedDependencies" type="bool">
      When the provider was handed pre-built dependencies, controls whether they are disposed alongside the provider. Defaults to `false` — the caller retains ownership.
    </ResponseField>

    <ResponseField name="authLinkProvider" type="CrossmintAuthLinkProvider?">
      Optional resolver for the OAuth callback URL. Leave null to use the default deep-link resolver.
    </ResponseField>

    <ResponseField name="startAuthCallbackRouter" type="bool">
      When `true` (default) the provider starts \[CrossmintAuthCallbackRouter] automatically so OAuth redirects land correctly.
    </ResponseField>

    <ResponseField name="autoLoadWallet" type="bool">
      When `true` (default) the provider triggers `ensureLoaded()` on the wallet controller once a session is detected.
    </ResponseField>

    <ResponseField name="jwt" type="String?">
      BYOA JWT — when supplied, the provider seeds `auth.setJwt(jwt)` on startup (Bring Your Own Auth). Apps not using BYOA can leave this null.
    </ResponseField>

    <ResponseField name="otpPromptBuilder" type="CrossmintOtpPromptBuilder?">
      Builder for the default OTP prompt UI — pass `crossmintDefaultOtpPromptBuilder` for the Material default. Leave null to drive OTP UI headlessly via `walletController.otp`.
    </ResponseField>

    <ResponseField name="mountBridgeHosts" type="bool">
      When `true` (default) the provider mounts `CrossmintWalletHost` so the hidden signer bridge has a place to run. Set to `false` only if your subtree already hosts the bridge.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="child" type="Widget" required>
  The subtree rendered once dependencies are ready. Pair with \[CrossmintWalletGate] to show a loading state until then.
</ResponseField>

### Usage

```dart theme={null}
import 'package:crossmint_flutter/crossmint_flutter_ui.dart';

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: CrossmintWalletProvider(
        config: CrossmintWalletProviderConfig(
          clientConfig: CrossmintClientConfig(
            apiKey: 'YOUR_CLIENT_API_KEY',
            appScheme: 'myapp',
          ),
          walletControllerConfig: CrossmintWalletControllerConfig(
            createOnLogin: CrossmintCreateOnLoginConfig(
              chain: 'base-sepolia',
              recovery: const CrossmintEmailSignerConfig(),
            ),
            showOtpSignerPrompt: true,
          ),
          otpPromptBuilder: crossmintDefaultOtpPromptBuilder,
        ),
        child: const HomeScreen(),
      ),
    );
  }
}
```

***

## CrossmintWalletControllerConfig

Configuration for the wallet controller, used by both `CrossmintWalletProvider` and the headless `CrossmintClient.createWalletController()`.

<ResponseField name="createOnLogin" type="CrossmintCreateOnLoginConfig?">
  When set, the controller automatically creates (or loads) a wallet on the given chain once the user is authenticated. Fill `recovery` with the recovery signer config (e.g. `CrossmintEmailSignerConfig()`).
</ResponseField>

<ResponseField name="showOtpSignerPrompt" type="bool">
  Whether the SDK should surface the default OTP prompt automatically. Set to `false` to drive OTP UI yourself by listening to \[CrossmintWalletController.otp].
</ResponseField>

<ResponseField name="callbacks" type="CrossmintWalletLifecycleCallbacks?">
  Optional lifecycle hooks — see \[CrossmintWalletLifecycleCallbacks].

  <Expandable title="properties">
    <ResponseField name="onWalletCreationStart" type="Future<void> Function()?">
      Called immediately before the controller issues a `createWallet` API call. Await the returned future to block the operation until your UI is ready.
    </ResponseField>

    <ResponseField name="onTransactionStart" type="Future<void> Function()?">
      Called immediately before the controller issues a create-transaction API call. Await to block until your UI is ready.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="deviceSignerKeyStorage" type="DeviceSignerKeyStorage?">
  Storage adapter used to persist device-signer keys. Defaults to a secure-enclave / keystore-backed implementation on device.
</ResponseField>

***

## CrossmintClientScope

Low-level scope that provides a `CrossmintClient` instance to the widget subtree.

Access the client from descendant widgets:

```dart theme={null}
final client = CrossmintClientScope.of(context);
```

### Usage

```dart theme={null}
import 'package:crossmint_flutter/crossmint_flutter_ui.dart';

CrossmintClientScope(
  config: CrossmintClientConfig(
    apiKey: 'YOUR_CLIENT_API_KEY',
    appScheme: 'myapp',
  ),
  child: const MyApp(),
)
```

***

## CrossmintAuthScope

Provides the auth client to the widget subtree. Must be nested inside a `CrossmintClientScope`.

### Usage

```dart theme={null}
CrossmintClientScope(
  config: CrossmintClientConfig(apiKey: 'YOUR_CLIENT_API_KEY'),
  child: CrossmintAuthScope(
    child: const LoginScreen(),
  ),
)
```

***

## CrossmintWalletScope

Provides the wallet controller to the widget subtree. Must be nested inside a `CrossmintClientScope`.

### Usage

```dart theme={null}
CrossmintClientScope(
  config: CrossmintClientConfig(apiKey: 'YOUR_CLIENT_API_KEY'),
  child: CrossmintWalletScope(
    config: CrossmintWalletControllerConfig(
      createOnLogin: CrossmintCreateOnLoginConfig(
        chain: 'base-sepolia',
        recovery: const CrossmintEmailSignerConfig(),
      ),
    ),
    child: const WalletScreen(),
  ),
)
```

***

## CrossmintWalletGate

Status-based widget that renders different builders depending on the wallet state. Must be used within a `CrossmintWalletProvider` or `CrossmintWalletScope`.

All builders receive a `CrossmintWalletContextData` object, which provides access to the current state, auth client, wallet controller, and actions.

### Props

<ResponseField name="readyBuilder" type="CrossmintWalletGateBuilder" required />

<ResponseField name="initializingBuilder" type="CrossmintWalletGateBuilder?" />

<ResponseField name="unauthenticatedBuilder" type="CrossmintWalletGateBuilder?" />

<ResponseField name="errorBuilder" type="CrossmintWalletGateBuilder?" />

### Usage

```dart theme={null}
CrossmintWalletGate(
  readyBuilder: (context, data) {
    // readyBuilder fires once authenticated — the wallet may
    // still be loading. Guard on hasWallet before accessing it.
    if (!data.state.hasWallet) {
      return const Center(child: CircularProgressIndicator());
    }
    return DashboardScreen(wallet: data.state.currentWallet!);
  },
  unauthenticatedBuilder: (context, data) => const LoginScreen(),
  initializingBuilder: (context, data) => const Center(
    child: CircularProgressIndicator(),
  ),
)
```
