> ## 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.

# CrossmintWalletOtpController

> Flutter Final Class

**Final Class**

Drives OTP challenges raised by non-custodial email and phone signers.

```dart theme={null}
final class CrossmintWalletOtpController
```

Exposed on `CrossmintWalletController.otp`. When the signer flow requests
authentication, the controller populates `pendingChallenge` and exposes
`sendOtp` / `verifyOtp` / `reject` to drive it. UI code observes
`challengeListenable` to show a prompt.

```dart theme={null}
ValueListenableBuilder<CrossmintOtpChallenge?>(
  valueListenable: walletController.otp.challengeListenable,
  builder: (context, challenge, _) {
    if (challenge == null) return const SizedBox.shrink();
    return MyOtpDialog(
      onSubmit: walletController.otp.verifyOtp,
      onCancel: walletController.otp.reject,
    );
  },
);
```

## Properties

### needsAuth

```dart theme={null}
bool get needsAuth
```

`true` when an OTP challenge is outstanding.

### pendingChallenge

```dart theme={null}
CrossmintOtpChallenge? get pendingChallenge
```

The active challenge, or `null` when no OTP is pending.

### challengeListenable

```dart theme={null}
ValueListenable<CrossmintOtpChallenge?> get challengeListenable
```

Reactive handle on the pending challenge — subscribe to drive OTP UI.

## Methods

### onAuthRequired

```dart theme={null}
Future<void> onAuthRequired(
  String signerType,
  String signerLocator,
  bool needsAuth,
  CrossmintOtpSendCallback sendOtp,
  CrossmintOtpVerifyCallback verifyOtp,
  CrossmintOtpRejectCallback reject,
)
```

Entry point the SDK calls when a signer needs authentication. Normally invoked by the signer auto-recovery machinery — you should not need to call this yourself.

### sendOtp

```dart theme={null}
Future<void> sendOtp()
```

Requests that the Crossmint API (re-)send the OTP to the user. Throws `CrossmintSignerException` when no challenge is pending.

### verifyOtp

```dart theme={null}
Future<void> verifyOtp(String otp)
```

Submits the OTP the user entered. On success, clears the pending challenge. Throws `CrossmintSignerException` when no challenge is pending.

### reject

```dart theme={null}
void reject([Object? error])
```

Cancels the pending OTP flow, surfacing `error` (if any) to the signer request that raised the challenge.

### clear

```dart theme={null}
void clear()
```

Clears any pending challenge without notifying the signer. Prefer `verifyOtp` or `reject` to resolve a challenge cleanly.

### dispose

```dart theme={null}
void dispose()
```

Releases the underlying `ValueNotifier`. Called automatically when the parent `CrossmintWalletController` is disposed.
