@lightningresearch/sdk
v1.2.1
Published
Lightning Research Device Intelligence SDK
Maintainers
Readme
@lightningresearch/sdk
Device intelligence SDK for Lightning Research. Identifies devices with a stable fingerprint ID, detects bots, assesses threats, and provides network intelligence — all from the browser.
Installation
npm / yarn / pnpm
npm install @lightningresearch/sdkThe npm package ships the module builds only. The browser <script> bundle is hosted separately and should be loaded from the public SDK URL below.
The runtime sdkVersion is derived from the package metadata at build time, so the shipped client and the package version stay aligned.
CDN (script tag)
<script src="https://lrdefender.lightningresearch.ai/sdk/v1/lr.min.js"></script>For Subresource Integrity (recommended):
<script
src="https://lrdefender.lightningresearch.ai/sdk/v1/lr.min.js"
integrity="sha384-<HASH>"
crossorigin="anonymous"
></script>The current SRI hash is published with each release. Contact your account manager or check the deploy logs for the latest integrity value.
The CDN build exposes window.LightningResearchSDK.LightningResearch.
Quick Start
npm (ES modules / CommonJS)
import { LightningResearch } from '@lightningresearch/sdk';
const lr = new LightningResearch({ sessionToken: 'short-lived-session-token' });
const result = await lr.identify();
console.log(result.deviceId, result.confidence, result.risk.level);CDN
<script src="https://lrdefender.lightningresearch.ai/sdk/v1/lr.min.js"></script>
<script>
const lr = new LightningResearchSDK.LightningResearch({ sessionToken: 'short-lived-session-token' });
lr.identify().then(result => {
console.log(result.deviceId, result.confidence);
});
</script>Configuration
const lr = new LightningResearch({
apiKey: 'lr_...', // optional: for server-side secret use only
sessionToken: 'eyJ...', // optional: preferred for browser collection
endpoint: 'https://...', // optional: custom API endpoint
region: 'us', // optional: 'us' | 'eu' | 'auto'
timeout: 10000, // optional: request timeout in ms (default 10000)
signals: { // optional: toggle individual signal collectors
canvas: true,
audio: true,
webgl: true,
webglTasks: true,
fonts: true,
domRect: true,
math: true,
cssMedia: true,
storage: true,
adBlock: true,
gpuTiming: true, // high-cost probe, enabled by default
wasmTiming: true, // high-cost probe, enabled by default
webrtc: true, // local network entropy (hashed, privacy-safe)
},
privacy: { // optional: GDPR / consent controls
consentRequired: false, // if true, identify() throws until setConsent(true)
respectDoNotTrack: false, // if true, identify() throws when DNT=1
},
});Use exactly one browser-facing credential path:
sessionToken: preferred for browsers; issue it server-side viaPOST /api/collector/sessionapiKey: keep server-side only for direct API usage
If you need to reduce runtime cost, disable gpuTiming and wasmTiming explicitly. They are enabled by default because they materially improve matching fidelity.
API Reference
lr.identify(options?)
Collect the device fingerprint and send it to the server for identification.
const result = await lr.identify({ tag: 'login', linkedId: 'user-123' });Returns IdentifyResponse:
| Field | Type | Description |
|-------|------|-------------|
| deviceId | string | Stable device identifier |
| confidence | number | Match confidence 0–100 |
| matchType | string | How the device was matched |
| risk | { level, score, factors } | Risk assessment |
| isNewDevice | boolean | Whether this is a first-time device |
| visitCount | number | Total visits from this device |
| requestId | string | Unique request identifier |
lr.getDevice(deviceId)
Retrieve a previously identified device.
const device = await lr.getDevice('abc123');Returns DeviceResponse with deviceId, confidence, matchType, visitCount, browserCount, firstSeen, lastSeen, blocked, etc.
lr.startBehavioralTracking()
Start collecting behavioral biometrics (mouse, keyboard, scroll, touch). Call early in the page lifecycle for the best signal coverage. Data is automatically included in identify() and bot.detect().
lr.startBehavioralTracking();
// Later, when done:
lr.stopBehavioralTracking();lr.bot.detect(fingerprint?, behavioral?)
Run bot detection. If behavioral tracking is active, data is included automatically.
const bot = await lr.bot.detect();
// { isBot: false, botScore: 0.12, detectionMethod: 'behavioral', confidence: 0.95 }lr.bot.analyzeBehavior(behavioral?)
Analyze behavioral signals (mouse movements, keystrokes, scroll patterns). Uses tracked data automatically if startBehavioralTracking() was called.
lr.threat.assess(ip)
Assess threat level for an IP address.
const threat = await lr.threat.assess('1.2.3.4');
// { threatScore: 85, isProxy: true, isVpn: false, isTor: false, country: 'US' }lr.threat.lookup(ip)
Look up IP reputation and known threats.
lr.threat.recent(limit?)
Get recent threat events for your tenant.
lr.network.analyze(ip?)
Analyze network characteristics (proxy, VPN, datacenter detection).
lr.network.lookup(ip)
Look up detailed IP intelligence.
lr.analytics.query(params?)
Query device analytics data.
lr.analytics.export(params?)
Export analytics data.
Error Handling
The SDK throws standard Error instances in the following cases:
try {
const result = await lr.identify();
} catch (err) {
// err.message will be one of:
// - 'apiKey or sessionToken is required' (constructor misconfiguration)
// - 'endpoint must use HTTPS' (non-HTTPS endpoint)
// - 'endpoint must be a valid Lightning Research API host'
// - 'Consent is required before collecting'
// - 'Do Not Track is enabled'
// - 'Authentication failed' (401/403 from API)
// - 'Rate limited' (429 from API)
// - 'Request failed (NNN)' (other HTTP errors)
console.error('LR SDK error:', err.message);
}Network failures (DNS, timeout, CORS) propagate as the browser's native TypeError from fetch(). Wrap calls in try/catch for production resilience.
Privacy & Consent
For GDPR, ePrivacy, or CCPA compliance:
const lr = new LightningResearch({
sessionToken: 'short-lived-session-token',
privacy: {
consentRequired: true,
respectDoNotTrack: true,
},
});
// identify() will throw until consent is granted
lr.setConsent(true);
// Check consent status
lr.hasConsent(); // true
// Revoke consent
lr.setConsent(false);You can also disable specific signal collectors:
const lr = new LightningResearch({
sessionToken: 'short-lived-session-token',
signals: {
canvas: false, // disable canvas fingerprinting
audio: false, // disable audio fingerprinting
},
});Signals Collected
The SDK v1.2.0 collects 90+ browser signals across 30+ modules for maximum identification accuracy:
| Category | Signals | |----------|---------| | Navigator | userAgent, platform, language, languages, cores, memory, maxTouchPoints, cookieEnabled, doNotTrack, plugins, mimeTypes, userAgentData | | Screen | width, height, colorDepth, pixelDepth, screenAvailWidth, screenAvailHeight, devicePixelRatio, screenOrientation, physicalResolution, zoomDetection | | Canvas | Multi-scene rendering + 3 sub-scene hashes + full Canvas2D engine (V2 hash, extended scenes) | | Audio | OfflineAudioContext fingerprint, 32-bin peaks, impulse response, V2 fingerprint, binned frequency hash | | WebGL | Vendor, renderer, 15+ GPU parameters, extensions, capabilities (webglCaps) | | WebGL Tasks | 22 advanced procedural GPU scenes (textures, geometry, wireframe, projection, curves, multi-model, etc.) | | Fonts | Pixel-width metrics + full font list enumeration via full engine | | DOM Rects | BoundingClientRect + full engine clientRects analysis | | Math | 10 math constant precision tests (acos, acosh, cbrt, cosh, etc.) | | CSS | System fonts, computed style fingerprints | | CSS Media | prefers-color-scheme, reduced-motion, pointer, hover, color-gamut, forced-colors, contrast | | Storage | localStorage, sessionStorage, indexedDB availability | | GPU Timing | DRAWNAPART-style draw-call timing traces (point, triangle, fragment workloads) | | Wasm Timing | Engine-level micro-benchmarks (call overhead, memory, math intrinsics) | | WebRTC | Hashed local candidates + full WebRTC device fingerprint | | Battery | Charging status, level, charge/discharge time | | Lies | API tampering / prototype lie detection across 197+ browser APIs | | Headless | Headless browser and automation detection | | Resistance | Tor, Brave, Firefox, privacy resistance detection | | Features | Browser engine identification (Blink, Gecko, WebKit) | | Window | Window property fingerprint | | Worker | Worker scope cross-validation | | Voices | Speech synthesis voice enumeration | | Media | MIME type and media capabilities fingerprint | | Intl | Internationalization API locale fingerprint | | SVG | SVG rendering fingerprint | | Document | HTML element version detection | | Writing Scripts | Installed writing systems and language scripts | | Console Errors | Console error signature fingerprint | | Bot Detection | Client-side bot detection (headless, automation, puppeteer) | | Behavioral | Mouse dynamics, keystroke timing, scroll patterns, touch gestures (opt-in) | | Other | Timezone, ad blocker, battery, zoom detection, trash/pollution detection |
All module outputs are hashed into serverAssist.hashes for compact, privacy-preserving transmission to the matching server.
TypeScript
Full TypeScript types are included. Key types:
import type {
LightningResearchOptions,
IdentifyResponse,
DeviceResponse,
BotDetectionResponse,
ThreatAssessmentResponse,
ThreatLookupResponse,
AnalyticsQueryResponse,
SignalsConfig,
PrivacyConfig,
} from '@lightningresearch/sdk';Browser Support
| Browser | Version | |---------|---------| | Chrome | 80+ | | Firefox | 78+ | | Safari | 14+ | | Edge | 80+ | | iOS Safari | 14+ | | Chrome Android | 80+ |
License
See LICENSE for details.
