From 946e6378e2dc4bd2ba385f321bce4c37fe447668 Mon Sep 17 00:00:00 2001
From: "fingerprint-dx-team-actions-runner[bot]"
<197604345+fingerprint-dx-team-actions-runner[bot]@users.noreply.github.com>
Date: Wed, 23 Sep 2026 15:12:59 +0000
Subject: [PATCH] chore(release): changeset created a new release (rc)
---
.changeset/pre.json | 4 +-
sdk/CHANGELOG.md | 152 ++++++++++++++++++++++++++++++++++++++
sdk/RNFingerprint.podspec | 2 +-
sdk/package.json | 2 +-
4 files changed, 157 insertions(+), 3 deletions(-)
diff --git a/.changeset/pre.json b/.changeset/pre.json
index de3f7e64..0bfe8cfb 100644
--- a/.changeset/pre.json
+++ b/.changeset/pre.json
@@ -5,6 +5,8 @@
"@fingerprint/react-native": "3.17.0"
},
"changesets": [
- "new-architecture-support"
+ "new-architecture-support",
+ "spm-support",
+ "v4-api-migration"
]
}
diff --git a/sdk/CHANGELOG.md b/sdk/CHANGELOG.md
index c15c4e5f..968299db 100644
--- a/sdk/CHANGELOG.md
+++ b/sdk/CHANGELOG.md
@@ -1,5 +1,157 @@
# @fingerprint/react-native
+## 4.0.0-rc.1
+
+### Major Changes
+
+- Migrated the SDK to Fingerprint API v4 and realigned the public API with `@fingerprint/react`. This is a breaking change on every platform (web, iOS, Android).
+
+ **Renamed API**
+
+ - `FingerprintJsProProvider` → `FingerprintProvider`.
+ - `FingerprintJsProAgent` (constructed with `new`) → `start(options)`, returning a client with a single `get(options)` method (`getVisitorId`/`getVisitorData` are removed).
+ - Added `useFingerprint()` to read the client from context.
+
+ **Single options object**
+
+ - `getData(tags, linkedId, options)` → `getData({ tags, linkedId, timeout })`.
+ - `useVisitorData` now returns a discriminated union (`data`/`isLoading`/`isFetched`/`error`), and `getData` always throws on error. The `throwOnError` option is removed. `immediate` defaults to `false`.
+
+ **Grouped provider/start options**
+
+ - Platform-only options are nested: `android` (`allowUseOfLocationData`, `locationTimeoutMillis`), `ios` (`allowUseOfLocationData`), `web` (`storageKeyPrefix`, `urlHashing`, `cache`). `locationTimeoutMillisAndroid` moves to `android.locationTimeoutMillis`.
+ - `endpointUrl` + `fallbackEndpointUrls` are replaced by a single `endpoints` (string or string[]).
+
+ **snake_case response**
+
+ - The response is now the flat, snake_case `FingerprintResponse` (`visitor_id`, `event_id`, `suspect_score?`, `sealed_result`), matching the Server API v4 and JS agent. `requestId` is replaced by `event_id`, `confidence` is removed, and `suspect_score` is a new optional Smart Signals value; `sealedResult` is renamed to `sealed_result`. The nested extended fields (`ipLocation`, `firstSeenAt`, etc.) and the `extendedResponseFormat` option are removed (v4 always returns the flat format).
+
+ **Single error type**
+
+ - The ~28 error classes are replaced by a single `FingerprintError` (`{ name, code, event_id }`) plus an `isFingerprintError` type guard. Discriminate on `error.code` (e.g. `too_many_requests`).
+ - Every network failure reports `code: 'network_error'` on all platforms. The platform-specific `network_unavailable` (Android), `network_connection` and `network_abort` (web) codes are not emitted.
+
+ **Web**
+
+ - The web implementation now uses `@fingerprint/agent` (v4) instead of `@fingerprintjs/fingerprintjs-pro-spa`. Install `@fingerprint/agent` as the web peer dependency.
+ - ️Caching is available only on **web** and is disabled by default. To enable caching on web, pass the JavaScript agent [cache](https://docs.fingerprint.com/reference/js-agent-start-function#cache) option:
+ ```jsx
+
+
+
+ ```
+
+ **iOS**:
+ - The new version floor for iOS is **15.1**.
+
+ **Android**:
+ - The new version floor for Android is **Android 7.0 (API level 24+)**.
+
+ ## Migration
+
+ **Provider**
+
+ ```diff
+ - import { FingerprintJsProProvider } from '@fingerprint/react-native'
+ + import { FingerprintProvider } from '@fingerprint/react-native'
+
+ -
+ +
+
+ -
+ +
+ ```
+
+ **Hook (`useVisitorData`)**
+
+ ```diff
+ - const { isLoading, error, data, getData } = useVisitorData()
+ + const { isLoading, isFetched, error, data, getData } = useVisitorData()
+
+ // positional args + opt-in throwing → single options object, always throws
+ - await getData({ userAction: 'login' }, 'user_1234', { timeout: 5000, throwOnError: true })
+ + await getData({ tags: { userAction: 'login' }, linkedId: 'user_1234', timeout: 5000 })
+
+ - data?.visitorId
+ - data?.confidence.score
+ + data?.visitor_id
+ + data?.suspect_score
+ ```
+
+ **Imperative client**
+
+ ```diff
+ - import { FingerprintJsProAgent } from '@fingerprint/react-native'
+ + import { start } from '@fingerprint/react-native'
+
+ - const client = new FingerprintJsProAgent({ apiKey: 'PUBLIC_API_KEY', region: 'eu' })
+ - const visitorId = await client.getVisitorId()
+ - const data = await client.getVisitorData()
+ + const fp = start({ apiKey: 'PUBLIC_API_KEY', region: 'eu' })
+ + const result = await fp.get()
+ + result.visitor_id
+ ```
+
+ **Provider / start options**
+
+ ```diff
+ {
+ apiKey: 'PUBLIC_API_KEY',
+ region: 'eu',
+ - endpointUrl: 'https://metrics.example.com',
+ - fallbackEndpointUrls: ['https://metrics2.example.com'],
+ + endpoints: ['https://metrics.example.com', 'https://metrics2.example.com'],
+ - extendedResponseFormat: true,
+ - allowUseOfLocationData: true,
+ - locationTimeoutMillisAndroid: 5000,
+ + android: { allowUseOfLocationData: true, locationTimeoutMillis: 5000 },
+ + ios: { allowUseOfLocationData: true },
+ }
+ ```
+
+ **Errors**
+
+ ```diff
+ - import { TooManyRequestError } from '@fingerprint/react-native'
+ + import { isFingerprintError } from '@fingerprint/react-native'
+
+ try {
+ await fp.get()
+ } catch (error) {
+ - if (error instanceof TooManyRequestError) {
+ + if (isFingerprintError(error) && error.code === 'too_many_requests') {
+ // handle rate limiting
+ }
+ }
+ ```
+
+ **Web peer dependency**
+
+ ```diff
+ - npm install @fingerprintjs/fingerprintjs-pro-spa
+ + npm install @fingerprint/agent
+ ```
+
+ --- ([64f1dfb](https://github.com/fingerprintjs/react-native/commit/64f1dfbc04ae9913a5cbccd9aad75a94949ea913))
+
+### Minor Changes
+
+- Added experimental support for [Swift Package Manager](https://swift.org/package-manager/). The library now ships with its own `Package.swift`.
+
+ If you are on React Native >= 0.87, you can run:
+
+ ```bash
+ cd ios
+ # deintegrate will remove CocoaPods from your project
+ npx react-native spm --deintegrate
+ ```
+
+ to consume the library via Swift Package Manager. ([7af274f](https://github.com/fingerprintjs/react-native/commit/7af274f34db8990e047bf6062f531ae2c6c73da4))
+
## 4.0.0-rc.0
### Major Changes
diff --git a/sdk/RNFingerprint.podspec b/sdk/RNFingerprint.podspec
index cb466384..0a064222 100644
--- a/sdk/RNFingerprint.podspec
+++ b/sdk/RNFingerprint.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "RNFingerprint"
- s.version = "3.17.1"
+ s.version = "4.0.0-rc.1"
s.summary = "Fingerprint Pro visitor identification in a React Native app"
s.description = "Official React Native client for Fingerprint. Best identification solution for React Native."
s.homepage = "https://github.com/fingerprintjs"
diff --git a/sdk/package.json b/sdk/package.json
index dce66ce2..1ac2381e 100644
--- a/sdk/package.json
+++ b/sdk/package.json
@@ -1,6 +1,6 @@
{
"name": "@fingerprint/react-native",
- "version": "4.0.0-rc.0",
+ "version": "4.0.0-rc.1",
"description": "Official React Native client for Fingerprint. Best identification solution for React Native.",
"main": "./dist/index.js",
"module": "./dist/esm/index.js",