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

# PIN management

> Set, rotate, verify, and remove the signing PIN.

The PIN gates `signMessage`, `signTransactionHash`, and `deleteWallet` when `requirePin: true`. It is stored only as a **salted PBKDF2-HMAC-SHA256 digest** inside `flutter_secure_storage` — the raw PIN never touches disk.

***

## Set a PIN

Call `setPin` once after wallet provisioning. The PIN must be exactly `BmoniEmbeddedSdk.pinLength` characters (default `6`).

```dart theme={null}
await BmoniEmbeddedSdk.setPin('123456');
```

Throws `pinAlreadySet` if a PIN already exists. Check first:

```dart theme={null}
if (!await BmoniEmbeddedSdk.hasPin()) {
  await BmoniEmbeddedSdk.setPin('123456');
}
```

***

## Check whether a PIN is set

```dart theme={null}
final bool hasPin = await BmoniEmbeddedSdk.hasPin();
```

***

## Verify a PIN without throwing

Use `matchPin` to check a PIN without triggering an exception. Useful for validating a user's entry before attempting a gated operation.

```dart theme={null}
final bool matches = await BmoniEmbeddedSdk.matchPin('123456');
if (!matches) {
  // Show "Incorrect PIN" to the user.
}
```

***

## Change a PIN

Requires the current PIN. Both the current and new PINs must be `pinLength` characters.

```dart theme={null}
await BmoniEmbeddedSdk.changePin(
  currentPin: '123456',
  newPin: '654321',
);
```

***

## Remove a PIN

Removes the stored digest entirely. After removal, `hasPin()` returns `false` and PIN-gated operations are unavailable until a new PIN is set.

```dart theme={null}
await BmoniEmbeddedSdk.removePin('123456');
```

***

## PIN length enforcement

All PIN operations enforce the `pinLength` set in `BmoniEmbeddedSdk.initialize`. Passing a PIN of the wrong length throws `BmoniSignerException(errorCode: pinInvalid)`.

You can read the required length at runtime to drive your UI:

```dart theme={null}
final int requiredLength = BmoniEmbeddedSdk.pinLength; // 6 by default

TextField(
  maxLength: requiredLength,
  keyboardType: TextInputType.number,
  // ...
)
```

***

## Full example

```dart theme={null}
// 1. One-time setup.
await BmoniEmbeddedSdk.setPin('123456');

// 2. Rotate the PIN.
await BmoniEmbeddedSdk.changePin(
  currentPin: '123456',
  newPin: '654321',
);

// 3. Verify without throwing — useful for a PIN confirmation step.
final bool ok = await BmoniEmbeddedSdk.matchPin('654321');
print('PIN matches: $ok'); // true

// 4. Tear down (e.g. on logout).
await BmoniEmbeddedSdk.removePin('654321');
```
