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:
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 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:
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:
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 |
| ThreatMetrix | 'threatmetrix' | threatmetrix.com |
Each provider has different capabilities, data collection methods, and geographic coverage. Visit the provider’s website to understand their specific features and limitations.
Methods
start()
Begins the device fingerprinting process.
This method:
- Loads the provider’s SDK asynchronously
- Initializes a fingerprinting session
- Begins collecting device characteristics
- Emits events as data is collected
Returns: void - The method does not return a value. Use events to track progress.
Example:
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.
on<EventName extends keyof Events>(
eventName: EventName,
handler: (...args: Events[EventName]) => void
): void
See Events section for available events.
off()
Removes an event listener.
off<EventName extends keyof Events>(
eventName: EventName,
handler: (...args: Events[EventName]) => void
): void
Events
The Device module emits events throughout the fingerprinting lifecycle:
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.
configuration_loaded
Emitted when the recipe configuration has been loaded and validated.
deviceComponent.on('configuration_loaded', (config) => {
console.log('Configuration loaded:', config);
});
Parameters:
| Parameter | Type | Description |
|---|
config | RecipeConfiguration | The loaded recipe configuration object. |
vendor_sdk_loaded
Common Event: This event is emitted by all vendor-based modules (IDV, OCR, Biometrics, Device).
Emitted when the provider’s SDK has been successfully loaded.
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
Common Event: This event is emitted by all vendor-based modules (IDV, OCR, Biometrics, Device).
Emitted when the provider’s SDK fails to load.
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.
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.
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. |
Emitted when device characteristics have been collected by the provider.
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.
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
// 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
-
Initialize Early
- Create the device component as early as possible in your user flow
- Device data collection improves with more time to gather signals
-
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
-
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:
- Check environment — Verify you are checking the correct environment (
sandbox vs production) in the dashboard. A mismatch here is the most common cause.
- Check clientID — Ensure the
clientID in your recipe matches what FrankieOne has configured for your account.
- Provider configured — Confirm with your FrankieOne account team that the device fingerprinting provider is enabled for your account before integrating.
- 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.
- Success indicator — Listen for
device_characteristics_extracted to confirm device data was captured client-side. If this event fires, data collection succeeded.
deviceComponent.on('device_characteristics_extracted', ({ deviceCharacteristics }) => {
console.log('Device data collected successfully');
});
- Timeline — How quickly device data appears in the dashboard depends on the vendor. Contact your FrankieOne account team for expected timing.