@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 +21 -0
- package/README.md +258 -0
- package/dist/chunk-FCBLJE3T.js +985 -0
- package/dist/chunk-FCBLJE3T.js.map +1 -0
- package/dist/flags-CwhHmaHQ.d.cts +606 -0
- package/dist/flags-CwhHmaHQ.d.ts +606 -0
- package/dist/hooks/index.cjs +1104 -0
- package/dist/hooks/index.cjs.map +1 -0
- package/dist/hooks/index.d.cts +65 -0
- package/dist/hooks/index.d.ts +65 -0
- package/dist/hooks/index.js +125 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/index.cjs +1011 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +69 -0
- package/dist/index.d.ts +69 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/package.json +66 -0
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).
|