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

# Device Module

> Device fingerprinting and fraud detection integration

## Overview

The Device module provides device fingerprinting capabilities through third-party fraud detection providers. It collects device characteristics and behavioral data to help identify and prevent fraudulent activities.

Device fingerprinting works by analyzing hardware, software, and behavioral patterns to create a unique device identifier. This helps detect anomalies, prevent account takeover, and identify suspicious activity patterns.

## Initializing the Module

The Device module is created using the `component()` factory method:

```javascript theme={null}
const deviceComponent = oneSdkInstance.component('device', {
  activityType: 'REGISTRATION'
});
```

### Module Options

All options are passed during module initialization:

| Parameter      | Type           | Required | Description                                                                                           |
| -------------- | -------------- | -------- | ----------------------------------------------------------------------------------------------------- |
| `activityType` | `ActivityType` | Yes      | The type of user activity being monitored. See [Activity Types](#activity-types) below.               |
| `sessionId`    | `string`       | No       | Custom session identifier. If not provided, a UUID will be generated automatically.                   |
| `token`        | `string`       | No       | Custom token for the fingerprinting session. If not provided, a UUID will be generated automatically. |

#### Activity Types

The activity type helps the fraud detection provider apply appropriate risk assessment rules:

| Value               | Description                           |
| ------------------- | ------------------------------------- |
| `REGISTRATION`      | User account creation or signup       |
| `LOGIN`             | User authentication or signin         |
| `CRYPTO_DEPOSIT`    | Cryptocurrency deposit transaction    |
| `CRYPTO_WITHDRAWAL` | Cryptocurrency withdrawal transaction |
| `FIAT_DEPOSIT`      | Fiat currency deposit transaction     |
| `FIAT_WITHDRAWAL`   | Fiat currency withdrawal transaction  |

Example with all options:

```javascript theme={null}
const deviceComponent = oneSdkInstance.component('device', {
  activityType: 'LOGIN',
  sessionId: 'custom-session-id',
  token: 'custom-token'
});
```

## Recipe Configuration

The Device module requires provider configuration in your recipe:

```javascript theme={null}
const oneSdkInstance = await OneSDK({
  session: { token: 'your-token' },
  recipe: {
    deviceCharacteristics: {
      provider: {
        name: 'sardine',
        clientID: 'your-client-id',
        environment: 'production'
      }
    }
  }
});
```

### Recipe Options

| Property                                     | Type                            | Required | Description                                                         |
| -------------------------------------------- | ------------------------------- | -------- | ------------------------------------------------------------------- |
| `deviceCharacteristics.provider.name`        | `'sardine'` \| `'threatmetrix'` | Yes      | The fraud detection provider to use.                                |
| `deviceCharacteristics.provider.clientID`    | `string`                        | Yes      | Your provider client ID. Contact FrankieOne support to obtain this. |
| `deviceCharacteristics.provider.environment` | `'production'` \| `'sandbox'`   | Yes      | The provider environment to use.                                    |

## Supported Providers

| Provider     | Value            | Learn More                                       |
| ------------ | ---------------- | ------------------------------------------------ |
| Sardine      | `'sardine'`      | [sardine.ai](https://sardine.ai)                 |
| ThreatMetrix | `'threatmetrix'` | [threatmetrix.com](https://www.threatmetrix.com) |

<Note>
  Each provider has different capabilities, data collection methods, and geographic coverage. Visit the provider's website to understand their specific features and limitations.
</Note>

## Methods

### start()

Begins the device fingerprinting process.

```typescript theme={null}
start(): void
```

This method:

1. Loads the provider's SDK asynchronously
2. Initializes a fingerprinting session
3. Begins collecting device characteristics
4. Emits events as data is collected

**Returns:** `void` - The method does not return a value. Use events to track progress.

**Example:**

```javascript theme={null}
const deviceComponent = oneSdkInstance.component('device', {
  activityType: 'REGISTRATION'
});

// Listen for events before starting
deviceComponent.on('device_characteristics_extracted', (data) => {
  console.log('Device data collected:', data.deviceCharacteristics);
});

deviceComponent.on('completed', (deviceDetails) => {
  console.log('Fingerprinting complete:', deviceDetails);
});

// Start the fingerprinting process
deviceComponent.start();
```

### on()

Registers an event listener.

```typescript theme={null}
on<EventName extends keyof Events>(
  eventName: EventName,
  handler: (...args: Events[EventName]) => void
): void
```

See [Events](#events) section for available events.

### off()

Removes an event listener.

```typescript theme={null}
off<EventName extends keyof Events>(
  eventName: EventName,
  handler: (...args: Events[EventName]) => void
): void
```

## Events

The Device module emits events throughout the fingerprinting lifecycle:

<Note>
  **Provider-Specific Behavior:** Event emissions and data structures may vary by provider. Not all providers emit all events. Always test with your chosen provider to understand which events are emitted and when.
</Note>

### configuration\_loaded

Emitted when the recipe configuration has been loaded and validated.

```typescript theme={null}
deviceComponent.on('configuration_loaded', (config) => {
  console.log('Configuration loaded:', config);
});
```

**Parameters:**

| Parameter | Type                  | Description                             |
| --------- | --------------------- | --------------------------------------- |
| `config`  | `RecipeConfiguration` | The loaded recipe configuration object. |

***

### vendor\_sdk\_loaded

<Note>
  **Common Event:** This event is emitted by all vendor-based modules (IDV, OCR, Biometrics, Device).
</Note>

Emitted when the provider's SDK has been successfully loaded.

```typescript theme={null}
deviceComponent.on('vendor_sdk_loaded', ({ vendor }) => {
  console.log('SDK loaded for:', vendor);
});
```

**Parameters:**

| Parameter | Type                            | Description                        |
| --------- | ------------------------------- | ---------------------------------- |
| `vendor`  | `'sardine'` \| `'threatmetrix'` | The provider whose SDK was loaded. |

***

### vendor\_sdk\_failed\_loading

<Note>
  **Common Event:** This event is emitted by all vendor-based modules (IDV, OCR, Biometrics, Device).
</Note>

Emitted when the provider's SDK fails to load.

```typescript theme={null}
deviceComponent.on('vendor_sdk_failed_loading', ({ vendor, errorObject }) => {
  console.error(`Failed to load ${vendor} SDK:`, errorObject);
});
```

**Parameters:**

| Parameter     | Type                            | Description                             |
| ------------- | ------------------------------- | --------------------------------------- |
| `vendor`      | `'sardine'` \| `'threatmetrix'` | The provider whose SDK failed to load.  |
| `errorObject` | `unknown`                       | The error that occurred during loading. |

***

### session\_data\_generated

Emitted when a fingerprinting session has been created with the provider.

```typescript theme={null}
deviceComponent.on('session_data_generated', ({ session }) => {
  console.log('Session created:', session);
});
```

**Parameters:**

| Parameter | Type      | Description                                                   |
| --------- | --------- | ------------------------------------------------------------- |
| `session` | `unknown` | Provider-specific session data. Structure varies by provider. |

***

### activity\_started

Emitted when an activity type has been set or updated.

```typescript theme={null}
deviceComponent.on('activity_started', ({ activityType }) => {
  console.log('Activity started:', activityType);
});
```

**Parameters:**

| Parameter      | Type           | Description                                                                |
| -------------- | -------------- | -------------------------------------------------------------------------- |
| `activityType` | `ActivityType` | The activity type that was started. See [Activity Types](#activity-types). |

***

### device\_characteristics\_extracted

Emitted when device characteristics have been collected by the provider.

```typescript theme={null}
deviceComponent.on('device_characteristics_extracted', ({ deviceCharacteristics }) => {
  console.log('Device data:', deviceCharacteristics);
});
```

**Parameters:**

| Parameter               | Type                                         | Description                                                                       |
| ----------------------- | -------------------------------------------- | --------------------------------------------------------------------------------- |
| `deviceCharacteristics` | `Record<string, string \| number \| object>` | Device data collected by the provider. Structure and properties vary by provider. |

***

### completed

Emitted when the fingerprinting process is complete.

```typescript theme={null}
deviceComponent.on('completed', (deviceDetails) => {
  console.log('Fingerprinting complete:', deviceDetails);
  // Proceed with your application flow
});
```

**Parameters:**

| Parameter       | Type                    | Description                                                   |
| --------------- | ----------------------- | ------------------------------------------------------------- |
| `deviceDetails` | `Record<string, never>` | Completion data. Currently empty but reserved for future use. |

## Complete Example

```javascript theme={null}
// Initialize OneSDK with device provider configuration
const oneSdkInstance = await OneSDK({
  session: {
    token: 'your-session-token'
  },
  recipe: {
    deviceCharacteristics: {
      provider: {
        name: 'sardine',
        clientID: 'your-sardine-client-id',
        environment: 'production'
      }
    }
  }
});

// Create device component
const deviceComponent = oneSdkInstance.component('device', {
  activityType: 'REGISTRATION'
});

// Listen for configuration load
deviceComponent.on('configuration_loaded', (config) => {
  console.log('Device module configured');
});

// Listen for SDK loading events
deviceComponent.on('vendor_sdk_loaded', ({ vendor }) => {
  console.log(`${vendor} SDK loaded successfully`);
});

deviceComponent.on('vendor_sdk_failed_loading', ({ vendor, errorObject }) => {
  console.error(`Failed to load ${vendor} SDK:`, errorObject);
  showError('Device fingerprinting unavailable');
});

// Listen for session creation
deviceComponent.on('session_data_generated', ({ session }) => {
  console.log('Fingerprinting session created');
});

// Listen for activity changes
deviceComponent.on('activity_started', ({ activityType }) => {
  console.log(`Activity: ${activityType}`);
});

// Listen for device data collection
deviceComponent.on('device_characteristics_extracted', ({ deviceCharacteristics }) => {
  console.log('Device characteristics collected:', deviceCharacteristics);
  // Data is automatically sent to FrankieOne backend
});

// Listen for completion
deviceComponent.on('completed', (deviceDetails) => {
  console.log('Device fingerprinting complete');
  // Continue with your verification flow
  proceedToNextStep();
});

// Start fingerprinting
deviceComponent.start();
```

## Best Practices

1. **Initialize Early**
   * Create the device component as early as possible in your user flow
   * Device data collection improves with more time to gather signals

2. **Handle SDK Loading Failures**
   * Always listen for `vendor_sdk_failed_loading` events
   * Have a fallback flow if device fingerprinting fails
   * Don't block user progress on fingerprinting completion

3. **Set Activity Type Appropriately**
   * Use the most specific activity type for your use case
   * Update activity type when user action changes (registration → transaction)
   * Accurate activity types improve fraud detection accuracy

## Common Issues

### Provider SDK fails to load

**Problem:** `vendor_sdk_failed_loading` event is emitted.

**Possible causes:**

* Network connectivity issues
* Content Security Policy (CSP) blocking the provider's SDK
* Invalid provider configuration (wrong clientID or environment)

**Solution:**

* Check your CSP headers allow the provider's domain
* Verify your `clientID` and `environment` are correct
* Check browser console for detailed error messages
* Contact FrankieOne support to verify your account configuration

***

### Configuration validation error

**Problem:** Module throws an error during initialization: "Your account is missing the environment configuration..."

**Cause:** The recipe configuration is missing required provider details.

**Solution:**

* Ensure `recipe.deviceCharacteristics.provider.name` is set
* Ensure `recipe.deviceCharacteristics.provider.environment` is set
* Ensure `recipe.deviceCharacteristics.provider.clientID` is set
* Contact FrankieOne support if you don't have these values

***

### Invalid activity type

**Problem:** Error thrown: "Activity Type should be one of the following..."

**Cause:** An invalid activity type was provided.

**Solution:**

* Use only the supported activity types: 'REGISTRATION', 'LOGIN', 'CRYPTO\_DEPOSIT', 'CRYPTO\_WITHDRAWAL', 'FIAT\_DEPOSIT', 'FIAT\_WITHDRAWAL'
* Check for typos in activity type strings
* Ensure you're using the exact string values (case-sensitive)

***

### Device data not appearing in dashboard

**Problem:** Fingerprinting completes but data doesn't appear in FrankieOne dashboard.

**Troubleshooting checklist:**

1. **Check environment** — Verify you are checking the correct environment (`sandbox` vs `production`) in the dashboard. A mismatch here is the most common cause.
2. **Check clientID** — Ensure the `clientID` in your recipe matches what FrankieOne has configured for your account.
3. **Provider configured** — Confirm with your FrankieOne account team that the device fingerprinting provider is enabled for your account before integrating.
4. **CSP blockage** — There is no direct client-side indicator that device data was blocked, other than the `vendor_sdk_failed_loading` event or CSP console errors. Check browser console for blocked requests.
5. **Success indicator** — Listen for `device_characteristics_extracted` to confirm device data was captured client-side. If this event fires, data collection succeeded.

```javascript theme={null}
deviceComponent.on('device_characteristics_extracted', ({ deviceCharacteristics }) => {
  console.log('Device data collected successfully');
});
```

6. **Timeline** — How quickly device data appears in the dashboard depends on the vendor. Contact your FrankieOne account team for expected timing.

## Related Resources

* [SDK Initialization](/docs/sdk-reference/sdk-initialization) - OneSDK setup and configuration
* [Individual Module](/docs/sdk-reference/individual-module) - Identity data collection
* [Session Management](/docs/sdk-reference/session-management) - Managing user sessions
