@simplr-ai/react-native 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Simplr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,258 @@
1
+ # @simplr-ai/react-native
2
+
3
+ React Native client SDK for the **Simplr** fraud & identity platform โ€” the mobile counterpart to the browser SDK (`@simplr-ai/js`) and the Flutter SDK (`simplr_fraud`). One package gives you:
4
+
5
+ - ๐Ÿ“ฑ **Device fingerprinting** โ€” a stable device signature + persistent device ID (no DOM/canvas; built from React Native APIs)
6
+ - ๐Ÿ‘† **Behavioral biometrics** โ€” touch/gesture dynamics (tap intervals, pressure, swipe velocity) to tell humans from bots
7
+ - ๐Ÿ›’ **Order fraud scoring** โ€” score transactions via `POST /v1/orders`
8
+ - ๐Ÿงช **Fraud checks** โ€” `POST /v1/check` with device + behavior signals
9
+ - ๐Ÿšฉ **Feature flags** โ€” local, deterministic evaluation (rollouts, targeting, rules), bucketing identical to every other SDK
10
+ - โš›๏ธ **React hooks** โ€” `useSimplr`, `useDeviceSignals`, `useFeatureFlag`, `useTouchBiometrics`
11
+
12
+ Use a **public key** (`pk_live_โ€ฆ` / `pk_test_โ€ฆ`) on the client. Keep secret keys on your backend.
13
+
14
+ Full docs: https://docs.simplr.so/docs/sdks/ (see the React Native page).
15
+
16
+ ## Install
17
+
18
+ ```bash
19
+ npm install @simplr-ai/react-native
20
+ # or: yarn add @simplr-ai/react-native
21
+ ```
22
+
23
+ `react` and `react-native` are peer dependencies (already present in any RN app).
24
+
25
+ ### Optional: persistent device IDs
26
+
27
+ For a device ID that survives app restarts, install AsyncStorage:
28
+
29
+ ```bash
30
+ npm install @react-native-async-storage/async-storage
31
+ ```
32
+
33
+ It is **optional** and lazily detected โ€” the SDK never hard-depends on it. Without it, the device ID is stable for the current app session (in-memory fallback).
34
+
35
+ ### Expo
36
+
37
+ Fully Expo-compatible. The core uses only `Platform`, `Dimensions`, `PixelRatio` and `Intl` โ€” no custom native modules and no config plugin required. AsyncStorage works in Expo too (`npx expo install @react-native-async-storage/async-storage`).
38
+
39
+ ## Quick start
40
+
41
+ ```ts
42
+ import { SimplrFraud } from "@simplr-ai/react-native";
43
+
44
+ const simplr = new SimplrFraud({ apiKey: "pk_live_xxx" });
45
+
46
+ // Run a fraud check โ€” device + behavior signals are auto-collected.
47
+ const result = await simplr.check({ email: "user@example.com" });
48
+ console.log(result.risk_score, result.risk_level);
49
+ ```
50
+
51
+ ## Device signals
52
+
53
+ ```ts
54
+ const signals = await simplr.getDeviceSignals();
55
+ // {
56
+ // fingerprint, device_id, device_id_created_at,
57
+ // platform: "ios" | "android", os, os_version, model, brand,
58
+ // screen_resolution, device_pixel_ratio, font_scale,
59
+ // timezone, timezone_offset, language, languages, is_emulator
60
+ // }
61
+ ```
62
+
63
+ The fingerprint is a stable hash built from OS + version, model/brand (when available), screen geometry + pixel ratio + font scale, timezone and locale.
64
+
65
+ ## check()
66
+
67
+ ```ts
68
+ const result = await simplr.check({
69
+ email: "user@example.com",
70
+ phone: "+15551234567",
71
+ event_type: "signup",
72
+ metadata: { plan: "growth" },
73
+ });
74
+ ```
75
+
76
+ Device and behavior signals are merged automatically (override by passing your own `device` / `behavior`).
77
+
78
+ ## Order scoring
79
+
80
+ ```ts
81
+ const order = await simplr.submitOrder({
82
+ order_id: "ord_123",
83
+ amount: 4999,
84
+ currency: "USD",
85
+ });
86
+ console.log(order.risk_score, order.risk_level);
87
+ ```
88
+
89
+ A `fingerprint_hash` is attached automatically when you don't provide one.
90
+
91
+ ## Feature flags
92
+
93
+ Flags are fetched once on `initialize()`, refreshed on an interval, then evaluated **locally** โ€” no network call per check. Bucketing uses the same MurmurHash3 as the server/browser/Node/Flutter SDKs, so a user lands in the same bucket everywhere.
94
+
95
+ ```ts
96
+ import { SimplrFlags } from "@simplr-ai/react-native";
97
+
98
+ const flags = new SimplrFlags();
99
+ await flags.initialize({ apiKey: "pk_live_xxx", environment: "live" });
100
+ flags.setUser("user_123"); // optional; falls back to "anonymous"
101
+
102
+ if (flags.isEnabled("new-checkout")) {
103
+ // โ€ฆ
104
+ }
105
+
106
+ // Per-call context for rules / targeting:
107
+ flags.isEnabled("new-checkout", { userId: "user_123", attributes: { plan: "growth" } });
108
+ ```
109
+
110
+ ## Profiles (`simplr.profiles`)
111
+
112
+ Anonymous user profiles + order fraud monitoring. The device fingerprint is auto-attached from the client's own device-signal collector.
113
+
114
+ ```ts
115
+ import { SimplrFraud } from "@simplr-ai/react-native";
116
+
117
+ const simplr = new SimplrFraud({ apiKey: "pk_live_xxx" });
118
+
119
+ // Create/update an anonymous profile and link this device.
120
+ const { profile, is_new } = await simplr.profiles.identify("user-123", { profileType: "customer" });
121
+
122
+ // Score an order (fingerprint auto-attached).
123
+ const result = await simplr.profiles.submitOrder({
124
+ order_id: "order-1",
125
+ external_id: "user-123",
126
+ amount: 4999,
127
+ currency: "USD",
128
+ });
129
+
130
+ // Read a user's risk profile, and report confirmed outcomes back.
131
+ const risk = await simplr.profiles.getProfileRisk("user-123");
132
+ await simplr.profiles.reportOutcome("user-123", "fraud"); // or "legitimate"
133
+ ```
134
+
135
+ You can also use `SimplrProfiles` standalone with `new SimplrProfiles({ apiKey })`.
136
+
137
+ ## RUM (`simplr.rum`)
138
+
139
+ Real User Monitoring. Events are batched and flushed to `/v1/rum/events` on a timer (`setInterval`). There are no native dependencies โ€” report screen views via `trackView()` (or the `useTrackView` hook) from your navigation listener.
140
+
141
+ ```ts
142
+ simplr.rum.initialize({ apiKey: "pk_live_xxx", applicationId: "my-app", environment: "production" });
143
+
144
+ simplr.rum.setUser("user-123", { plan: "pro" });
145
+ simplr.rum.addAttribute("buildNumber", "1.4.0");
146
+
147
+ simplr.rum.trackView("CheckoutScreen");
148
+ simplr.rum.trackAction("PressBuy", { sku: "abc" });
149
+ simplr.rum.log("info", "checkout opened");
150
+
151
+ try {
152
+ // โ€ฆ
153
+ } catch (err) {
154
+ simplr.rum.trackError(err as Error);
155
+ }
156
+
157
+ await simplr.rum.flush(); // force a flush
158
+ await simplr.rum.stopSession(); // emit session_end, flush, stop timer
159
+ ```
160
+
161
+ `SimplrRUM` is also available standalone (and as the shared `simplrRUM` singleton used by the hooks below).
162
+
163
+ ## AI delegation (`simplr.ai`)
164
+
165
+ OAuth-like AI authentication โ€” mint, validate, and revoke delegation tokens an end user shares with their AI agent.
166
+
167
+ ```ts
168
+ const delegation = await simplr.ai.createDelegation({
169
+ userId: "user-123",
170
+ binding: "verified_device",
171
+ fingerprintHash: (await simplr.getDeviceSignals()).fingerprint,
172
+ });
173
+
174
+ await simplr.ai.validate(token, { aiProvider: "anthropic", action: "read_orders" });
175
+ await simplr.ai.list("user-123");
176
+ await simplr.ai.get(delegation.delegationId);
177
+ await simplr.ai.stats();
178
+ await simplr.ai.revoke(delegation.delegationId, "user revoked");
179
+ await simplr.ai.revokeAllForUser("user-123", "logout"); // returns count
180
+ ```
181
+
182
+ > The browser SDK's interactive `connect()` popup flow relies on `window.open`/`postMessage` and is browser-only; it is intentionally omitted from the React Native SDK. Use `createDelegation()` to mint tokens directly.
183
+
184
+ ## Behavioral biometrics
185
+
186
+ A pure-JS touch-dynamics tracker fed by handlers you attach to a `View`:
187
+
188
+ ```ts
189
+ import { createTouchTracker } from "@simplr-ai/react-native";
190
+
191
+ const tracker = createTouchTracker();
192
+ tracker.start();
193
+ const h = tracker.getEventHandlers();
194
+
195
+ <View onTouchStart={h.onTouchStart} onTouchMove={h.onTouchMove} onTouchEnd={h.onTouchEnd}>
196
+ {/* โ€ฆ */}
197
+ </View>;
198
+
199
+ const metrics = tracker.getMetrics();
200
+ // { avgPressure, avgSwipeVelocity, avgTapInterval, avgTouchDuration, multiTouchCount, โ€ฆ }
201
+ ```
202
+
203
+ The SDK's own tracker (used by `check()`) is available via `simplr.getTouchTracker()`.
204
+
205
+ ## Hooks (`@simplr-ai/react-native/hooks`)
206
+
207
+ ```tsx
208
+ import {
209
+ useSimplr,
210
+ useDeviceSignals,
211
+ useFeatureFlag,
212
+ useTouchBiometrics,
213
+ useRum,
214
+ useTrackView,
215
+ useTrackAction,
216
+ useTrackError,
217
+ } from "@simplr-ai/react-native/hooks";
218
+
219
+ function Checkout() {
220
+ const simplr = useSimplr({ apiKey: "pk_live_xxx" });
221
+ const { signals, loading } = useDeviceSignals(simplr);
222
+ const showNewFlow = useFeatureFlag("new-checkout", { userId: "user_123" });
223
+ const { handlers } = useTouchBiometrics(simplr);
224
+
225
+ // RUM
226
+ useRum({ apiKey: "pk_live_xxx", applicationId: "my-app" }); // initialize once
227
+ useTrackView("CheckoutScreen"); // tracks on mount
228
+ const trackAction = useTrackAction();
229
+ const trackError = useTrackError();
230
+
231
+ return (
232
+ <View {...handlers}>
233
+ <Button title="Buy" onPress={() => trackAction("PressBuy", { sku: "abc" })} />
234
+ </View>
235
+ );
236
+ }
237
+ ```
238
+
239
+ | Hook | Returns |
240
+ | --- | --- |
241
+ | `useSimplr(config?)` | the configured `SimplrFraud` client |
242
+ | `useDeviceSignals(client?)` | `{ signals, loading, error, refresh }` |
243
+ | `useFeatureFlag(key, ctx?, flags?)` | `boolean` (re-evaluates as flags load) |
244
+ | `useTouchBiometrics(client?)` | `{ tracker, handlers, getMetrics }` |
245
+ | `useRum(config?)` | the shared `SimplrRUM` client (initializes it once) |
246
+ | `useTrackView(name, attrs?)` | `void` โ€” tracks a screen view on mount |
247
+ | `useTrackAction()` | `(name, attrs?) => void` |
248
+ | `useTrackError()` | `(error, attrs?) => void` |
249
+
250
+ All hooks guard their effects so they never crash during SSR or tests.
251
+
252
+ ## Configuration
253
+
254
+ `new SimplrFraud({ apiKey, baseUrl?, timeoutMs?, autoStart?, fetchImpl? })`. Every module accepts an optional `baseUrl` (defaults to `https://api.simplr.sh`, trailing slashes stripped) so you can point at any environment. Requests time out after 15s by default and raise a `SimplrError`.
255
+
256
+ ## License
257
+
258
+ MIT โ€” see [LICENSE](./LICENSE).