@advenue/react-native 0.3.1 → 0.5.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/README.md +2 -2
- package/android/build.gradle +22 -0
- package/android/src/main/AndroidManifest.xml +8 -0
- package/android/src/main/java/expo/modules/advenue/AdvenueAndroidModule.kt +354 -0
- package/dist/index.d.ts +214 -29
- package/dist/index.js +258 -141
- package/expo-module.config.json +9 -0
- package/ios/AdvenueIos.podspec +20 -0
- package/ios/AdvenueIosModule.swift +461 -0
- package/package.json +9 -19
- package/plugin/index.js +4 -8
- package/plugin/links.js +23 -1
- package/src/deep-links.ts +5 -2
- package/src/index.ts +413 -233
- package/src/native-storage.ts +63 -0
- package/src/native-types.ts +169 -0
- package/src/native.ts +27 -8
- package/src/secure-store.ts +7 -0
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { StorageAdapter, SecureStorageAdapter, DeepLink, AdvenueConfig, AdvenueClient, TrackOptions, Consent, DeviceInfo } from '@advenue/sdk-core';
|
|
2
2
|
export { AdvenueConfig, Consent, DeepLink, TrackOptions } from '@advenue/sdk-core';
|
|
3
|
-
import { AdvenueIosNativeModule, TrackingAuthorizationStatus } from '@advenue/sdk-ios';
|
|
4
|
-
export { TrackingAuthorizationStatus } from '@advenue/sdk-ios';
|
|
5
|
-
import { AdvenueAndroidNativeModule } from '@advenue/sdk-android';
|
|
6
3
|
|
|
7
4
|
/**
|
|
8
5
|
* Minimal structural type for the bits of `react-native-mmkv`'s MMKV instance
|
|
@@ -17,6 +14,172 @@ interface MMKVLike {
|
|
|
17
14
|
/** Wraps an MMKV instance as an Advenue StorageAdapter (synchronous, fast). */
|
|
18
15
|
declare function createMMKVStorage(mmkv: MMKVLike): StorageAdapter;
|
|
19
16
|
|
|
17
|
+
interface InstallReferrerResult {
|
|
18
|
+
referrer: string;
|
|
19
|
+
/** Device-clock: referrerClickTimestampSeconds. */
|
|
20
|
+
clickTimestamp: number;
|
|
21
|
+
/** Device-clock: installBeginTimestampSeconds. */
|
|
22
|
+
installTimestamp: number;
|
|
23
|
+
/**
|
|
24
|
+
* Server-clock: referrerClickTimestampServerSeconds (G1 fraud trust —
|
|
25
|
+
* referrerTrust:'server'). 0 = unverified; absent on older native builds.
|
|
26
|
+
*/
|
|
27
|
+
clickServerTimestamp?: number;
|
|
28
|
+
/** Server-clock: installBeginTimestampServerSeconds. 0 = unverified. */
|
|
29
|
+
installServerTimestamp?: number;
|
|
30
|
+
googlePlayInstant: boolean;
|
|
31
|
+
}
|
|
32
|
+
interface MetaInstallReferrerResult {
|
|
33
|
+
installReferrer: string;
|
|
34
|
+
isClickThrough: boolean;
|
|
35
|
+
actualTimestamp: number;
|
|
36
|
+
/** Which Meta app served the referrer (e.g. com.facebook.katana). */
|
|
37
|
+
provider: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Device metadata for Meta CAPI `extinfo` (Task 3n). Structurally mirrors
|
|
41
|
+
* `DeviceInfo` from `@advenue/shared` — kept as a local subset type (rather
|
|
42
|
+
* than importing that package) so this native-module-only package stays
|
|
43
|
+
* dependency-free; the RN facade's `collectDeviceInfo()` merges it into the
|
|
44
|
+
* real `DeviceInfo` shape.
|
|
45
|
+
*/
|
|
46
|
+
interface AdvenueDeviceInfo {
|
|
47
|
+
model?: string;
|
|
48
|
+
locale?: string;
|
|
49
|
+
carrier?: string;
|
|
50
|
+
timezone?: string;
|
|
51
|
+
screenWidth?: number;
|
|
52
|
+
screenHeight?: number;
|
|
53
|
+
screenDensity?: number;
|
|
54
|
+
cpuCores?: number;
|
|
55
|
+
totalStorageGb?: number;
|
|
56
|
+
freeStorageGb?: number;
|
|
57
|
+
}
|
|
58
|
+
interface AdvenueAndroidNativeModule {
|
|
59
|
+
/** Raw Play Install Referrer; parse with @advenue/install-referrer. */
|
|
60
|
+
getInstallReferrer(): Promise<InstallReferrerResult | null>;
|
|
61
|
+
/**
|
|
62
|
+
* Meta install referrer (null when no Facebook/Instagram app is installed);
|
|
63
|
+
* parse with parseMetaInstallReferrer from @advenue/install-referrer.
|
|
64
|
+
*/
|
|
65
|
+
getMetaInstallReferrer(): Promise<MetaInstallReferrerResult | null>;
|
|
66
|
+
/** Google Advertising ID (GAID) + limit-ad-tracking flag; null when unavailable. */
|
|
67
|
+
getAdvertisingId(): Promise<{
|
|
68
|
+
id: string;
|
|
69
|
+
limitAdTracking: boolean;
|
|
70
|
+
} | null>;
|
|
71
|
+
/** App Set ID — non-advertising, developer-scoped fallback id; null when unavailable. */
|
|
72
|
+
getAppSetId(): Promise<string | null>;
|
|
73
|
+
/**
|
|
74
|
+
* Play Integrity Standard API token (G3.1n).
|
|
75
|
+
*
|
|
76
|
+
* `requestHash` MUST be sha256_hex("<appId>:<deviceId>") — lowercase hex SHA-256
|
|
77
|
+
* of the literal string "<appId>:<deviceId>". The server's mapIntegrityVerdict
|
|
78
|
+
* re-derives the same string and compares it byte-for-byte.
|
|
79
|
+
*
|
|
80
|
+
* Rejects when:
|
|
81
|
+
* - ECONFIG: `io.advenue.INTEGRITY_CLOUD_PROJECT_NUMBER` meta-data is absent.
|
|
82
|
+
* - EUNSUPPORTED: Play Services unavailable or provider warming failed.
|
|
83
|
+
* - EINTEGRITY: Play returned an API-level error (network, quota, etc.).
|
|
84
|
+
*
|
|
85
|
+
* The JS bridge treats any rejection as "no attestation" and omits the token
|
|
86
|
+
* from the install event — rejection must never block the install track call.
|
|
87
|
+
*/
|
|
88
|
+
getIntegrityToken(requestHash: string): Promise<string>;
|
|
89
|
+
/**
|
|
90
|
+
* Device metadata (model, locale, screen, cpu, storage, timezone) used to
|
|
91
|
+
* populate Meta CAPI `extinfo` (Task 3n). Synchronous, best-effort — the JS
|
|
92
|
+
* facade (`collectDeviceInfo`) treats a thrown error as "unavailable" and
|
|
93
|
+
* degrades to `{}` rather than blocking anything.
|
|
94
|
+
*/
|
|
95
|
+
getDeviceInfo(): AdvenueDeviceInfo;
|
|
96
|
+
/**
|
|
97
|
+
* Built-in SDK storage (SharedPreferences `io.advenue.sdk`, MODE_PRIVATE) —
|
|
98
|
+
* the durable offline buffer + SDK state, so the app never supplies storage.
|
|
99
|
+
* Optional: absent on native builds predating this capability; the RN facade
|
|
100
|
+
* feature-detects and falls back to in-memory buffering. (No secure variant:
|
|
101
|
+
* Android has no reinstall-durable store — a reinstall legitimately re-fires
|
|
102
|
+
* the install, which the backend per-device window deduplicates.)
|
|
103
|
+
*/
|
|
104
|
+
storageGetItem?(key: string): string | null;
|
|
105
|
+
storageSetItem?(key: string, value: string): void;
|
|
106
|
+
storageRemoveItem?(key: string): void;
|
|
107
|
+
/**
|
|
108
|
+
* Android SSAID (Settings.Secure.ANDROID_ID) — signing-key-scoped, stable
|
|
109
|
+
* across reinstalls. The RN facade reads it ONLY when no usable GAID exists
|
|
110
|
+
* (Adjust-style fallback) and it is used strictly as a first-party
|
|
111
|
+
* fraud/dedup + reinstall-detection signal, never for ad attribution (Play
|
|
112
|
+
* policy). Optional: absent on older native builds; feature-detected.
|
|
113
|
+
*/
|
|
114
|
+
getAndroidId?(): string | null;
|
|
115
|
+
}
|
|
116
|
+
type TrackingAuthorizationStatus = 'notDetermined' | 'restricted' | 'denied' | 'authorized';
|
|
117
|
+
interface AdvenueIosNativeModule {
|
|
118
|
+
registerAppForAttribution(): void;
|
|
119
|
+
/**
|
|
120
|
+
* Conversion value: fine 0–63, coarse 'low'|'medium'|'high'. Updates the
|
|
121
|
+
* SKAN 4.0 postback, and on iOS 17.4+ the AdAttributionKit postback too.
|
|
122
|
+
*/
|
|
123
|
+
updateConversionValue(fineValue: number, coarse: string, lockWindow: boolean): Promise<void>;
|
|
124
|
+
/** Apple Search Ads attribution token (resolve server-side). */
|
|
125
|
+
getAttributionToken(): Promise<string | null>;
|
|
126
|
+
/**
|
|
127
|
+
* Shows the ATT consent prompt; requires NSUserTrackingUsageDescription in
|
|
128
|
+
* the app's Info.plist. Resolves with the resulting status.
|
|
129
|
+
*/
|
|
130
|
+
requestTrackingAuthorization(): Promise<TrackingAuthorizationStatus>;
|
|
131
|
+
getTrackingAuthorizationStatus(): TrackingAuthorizationStatus;
|
|
132
|
+
getAdvertisingId(): Promise<string | null>;
|
|
133
|
+
/** Vendor-scoped device id (IDFV) — available without ATT; a fallback anchor. */
|
|
134
|
+
getIdentifierForVendor(): string | null;
|
|
135
|
+
/** Clipboard match token (advmatch:<id>) for deterministic deferred deep linking; null if absent. */
|
|
136
|
+
getPasteboardMatchToken(): string | null;
|
|
137
|
+
/**
|
|
138
|
+
* G3.2n — App Attest. Generates (or reuses a keychain-cached) DCAppAttest
|
|
139
|
+
* key, computes clientDataHash = SHA-256(challenge), and calls
|
|
140
|
+
* DCAppAttestService.attestKey. Resolves { keyId, attestationObject } where
|
|
141
|
+
* attestationObject is a base64-encoded CBOR attestation for the server.
|
|
142
|
+
* Rejects with code EUNSUPPORTED on simulators (isSupported == false).
|
|
143
|
+
*/
|
|
144
|
+
attestKey(challenge: string): Promise<{
|
|
145
|
+
keyId: string;
|
|
146
|
+
attestationObject: string;
|
|
147
|
+
}>;
|
|
148
|
+
/**
|
|
149
|
+
* G3.3n — DeviceCheck. Calls DCDevice.current.generateToken to obtain the
|
|
150
|
+
* opaque base64 token that identifies this physical device to the Apple
|
|
151
|
+
* DeviceCheck API. The server queries/updates the persistent 2-bit per-device
|
|
152
|
+
* flag to detect reinstall abuse. Rejects with code EUNSUPPORTED on devices
|
|
153
|
+
* where DCDevice.current.isSupported is false (simulator, Catalyst, etc.).
|
|
154
|
+
*/
|
|
155
|
+
getDeviceCheckToken(): Promise<string>;
|
|
156
|
+
/**
|
|
157
|
+
* Device metadata (model, locale, screen, cpu, storage, timezone) used to
|
|
158
|
+
* populate Meta CAPI `extinfo` (Task 3n). Synchronous, best-effort — the JS
|
|
159
|
+
* facade (`collectDeviceInfo`) treats a thrown error as "unavailable" and
|
|
160
|
+
* degrades to `{}` rather than blocking anything.
|
|
161
|
+
*/
|
|
162
|
+
getDeviceInfo(): AdvenueDeviceInfo;
|
|
163
|
+
/**
|
|
164
|
+
* Built-in SDK storage (UserDefaults suite `io.advenue.sdk`) — the durable
|
|
165
|
+
* offline buffer + SDK state, so the app never supplies storage. Optional:
|
|
166
|
+
* absent on native builds predating this capability; the RN facade
|
|
167
|
+
* feature-detects and falls back to in-memory buffering.
|
|
168
|
+
*/
|
|
169
|
+
storageGetItem?(key: string): string | null;
|
|
170
|
+
storageSetItem?(key: string, value: string): void;
|
|
171
|
+
storageRemoveItem?(key: string): void;
|
|
172
|
+
/**
|
|
173
|
+
* Built-in secure storage (Keychain, kSecAttrAccessibleAfterFirstUnlock,
|
|
174
|
+
* ThisDeviceOnly) — survives app reinstall, which is what makes the device
|
|
175
|
+
* identity and the install guard reinstall-resilient (Adjust-style).
|
|
176
|
+
* Optional: absent on older native builds; feature-detected.
|
|
177
|
+
*/
|
|
178
|
+
secureGetItem?(key: string): string | null;
|
|
179
|
+
secureSetItem?(key: string, value: string): void;
|
|
180
|
+
secureRemoveItem?(key: string): void;
|
|
181
|
+
}
|
|
182
|
+
|
|
20
183
|
/**
|
|
21
184
|
* Minimal structural type for the bits of `expo-secure-store` we use. Declared
|
|
22
185
|
* locally so this package needs no expo types at compile time — the app passes
|
|
@@ -25,6 +188,8 @@ declare function createMMKVStorage(mmkv: MMKVLike): StorageAdapter;
|
|
|
25
188
|
interface SecureStoreLike {
|
|
26
189
|
getItemAsync(key: string): Promise<string | null>;
|
|
27
190
|
setItemAsync(key: string, value: string): Promise<void>;
|
|
191
|
+
/** Optional — forwarded so GDPR erasure can wipe the durable entries. */
|
|
192
|
+
deleteItemAsync?(key: string): Promise<void>;
|
|
28
193
|
}
|
|
29
194
|
/** Wraps expo-secure-store as an Advenue SecureStorageAdapter (async, durable). */
|
|
30
195
|
declare function createSecureStore(secureStore: SecureStoreLike): SecureStorageAdapter;
|
|
@@ -38,9 +203,11 @@ declare function createSecureStore(secureStore: SecureStoreLike): SecureStorageA
|
|
|
38
203
|
declare function parseDirectLink(url: string): DeepLink;
|
|
39
204
|
|
|
40
205
|
/**
|
|
41
|
-
* Lazy access to the
|
|
42
|
-
*
|
|
43
|
-
*
|
|
206
|
+
* Lazy access to the native modules that ship inside this package (ios/ and
|
|
207
|
+
* android/, registered via expo-module.config.json). `requireNativeModule`
|
|
208
|
+
* throws when the native side isn't built (Expo Go, web, missing pods), so
|
|
209
|
+
* resolution happens inside try/catch — never at module scope.
|
|
210
|
+
* expo-modules-core is resolved from the consuming app's Expo install.
|
|
44
211
|
*/
|
|
45
212
|
declare function getIosNative(): AdvenueIosNativeModule | null;
|
|
46
213
|
declare function getAndroidNative(): AdvenueAndroidNativeModule | null;
|
|
@@ -80,20 +247,26 @@ declare function collectDeviceInfo(natives: {
|
|
|
80
247
|
* paste banner — the user-visible, privacy-forward deferred path.)
|
|
81
248
|
*/
|
|
82
249
|
declare function resolveClipboardMatch(): Promise<DeepLink | null>;
|
|
83
|
-
interface RNAdvenueConfig extends Omit<AdvenueConfig, 'storage'> {
|
|
250
|
+
interface RNAdvenueConfig extends Omit<AdvenueConfig, 'storage' | 'platform'> {
|
|
251
|
+
/**
|
|
252
|
+
* Auto-detected from React Native's `Platform.OS` — omit it. Pass explicitly
|
|
253
|
+
* only outside a React Native runtime (tests, custom embeddings); `ios` and
|
|
254
|
+
* `android` map verbatim, any other RN target (web, desktop) reports as
|
|
255
|
+
* `web`.
|
|
256
|
+
*/
|
|
257
|
+
platform?: AdvenueConfig['platform'];
|
|
84
258
|
/**
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
* Omit to fall back to in-memory buffering (events lost on cold start).
|
|
259
|
+
* @internal Storage override (tests / custom embeddings). The SDK persists
|
|
260
|
+
* via its own native modules (UserDefaults/SharedPreferences) — apps never
|
|
261
|
+
* supply storage. When set, it replaces the built-in native storage.
|
|
89
262
|
*/
|
|
90
263
|
mmkv?: MMKVLike;
|
|
91
264
|
/**
|
|
92
265
|
* G3.1n — Play Integrity (Android) / App Attest (iOS) attestation.
|
|
93
266
|
*
|
|
94
|
-
* Your app's Advenue appId (the UUID
|
|
95
|
-
* Android,
|
|
96
|
-
*
|
|
267
|
+
* Your app's Advenue appId (the UUID in Settings → API Keys). When set on
|
|
268
|
+
* Android, the automatic install obtains a Play Integrity Standard token and
|
|
269
|
+
* attaches it to the install event. The requestHash is computed as
|
|
97
270
|
* `sha256Hex("<appId>:<deviceId>")`, matching the server's verification
|
|
98
271
|
* formula exactly (see `makeDecodeAndroid` in the worker).
|
|
99
272
|
*
|
|
@@ -101,10 +274,10 @@ interface RNAdvenueConfig extends Omit<AdvenueConfig, 'storage'> {
|
|
|
101
274
|
*/
|
|
102
275
|
appId?: string;
|
|
103
276
|
/**
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
*
|
|
277
|
+
* @internal Secure-store override (tests / custom embeddings). The SDK uses
|
|
278
|
+
* its own Keychain-backed native storage on iOS for the reinstall-resilient
|
|
279
|
+
* device identity — apps never supply a secure store. When set, it replaces
|
|
280
|
+
* the built-in Keychain adapter.
|
|
108
281
|
*/
|
|
109
282
|
secureStore?: SecureStoreLike;
|
|
110
283
|
/**
|
|
@@ -115,6 +288,13 @@ interface RNAdvenueConfig extends Omit<AdvenueConfig, 'storage'> {
|
|
|
115
288
|
* to distinguish the two. Omit to disable deep-link handling entirely.
|
|
116
289
|
*/
|
|
117
290
|
onDeepLink?: (link: DeepLink) => void;
|
|
291
|
+
/**
|
|
292
|
+
* @internal Test hook — disables the automatic install fired by
|
|
293
|
+
* `initialize()`. Install tracking is always automatic in production (there
|
|
294
|
+
* is no public `trackInstall`); tests turn it off to exercise the internal
|
|
295
|
+
* install path deterministically.
|
|
296
|
+
*/
|
|
297
|
+
autoTrackInstall?: boolean;
|
|
118
298
|
}
|
|
119
299
|
/**
|
|
120
300
|
* Maps a React Native AppState status to the client's session lifecycle hooks.
|
|
@@ -134,18 +314,10 @@ declare const Advenue: {
|
|
|
134
314
|
* where ATT doesn't exist) and forwards the result to the consent gate.
|
|
135
315
|
*/
|
|
136
316
|
requestTrackingAuthorization(): Promise<TrackingAuthorizationStatus>;
|
|
137
|
-
|
|
138
|
-
* Tracks the install event enriched with native attribution data: Play +
|
|
139
|
-
* Meta install referrers on Android, SKAdNetwork registration on iOS.
|
|
140
|
-
* Safe to call on every launch — when a `secureStore` is wired it fires at
|
|
141
|
-
* most once per device (reinstall-resilient on iOS via Keychain; Android
|
|
142
|
-
* re-fires after a reinstall, which is unavoidable post-GAID).
|
|
143
|
-
*/
|
|
144
|
-
trackInstall(properties?: Record<string, unknown>): Promise<void>;
|
|
145
|
-
setTrackingConsent: (granted: boolean) => void;
|
|
317
|
+
setTrackingConsent(granted: boolean): void;
|
|
146
318
|
getTrackingConsent: () => boolean;
|
|
147
319
|
/** GDPR/CCPA erasure: stop tracking and wipe local identifiers/queue. */
|
|
148
|
-
forgetMe
|
|
320
|
+
forgetMe(): void;
|
|
149
321
|
setConsentData(consent: Consent): void;
|
|
150
322
|
getConsentData: () => {
|
|
151
323
|
isUserSubjectToGDPR: boolean;
|
|
@@ -157,5 +329,18 @@ declare const Advenue: {
|
|
|
157
329
|
getDeviceId: () => string;
|
|
158
330
|
shutdown(): void;
|
|
159
331
|
};
|
|
332
|
+
/**
|
|
333
|
+
* Tracks the install event enriched with native attribution data: Play + Meta
|
|
334
|
+
* install referrers on Android, SKAdNetwork registration on iOS. Fired
|
|
335
|
+
* automatically by `initialize()` (or its consent deferral); when a
|
|
336
|
+
* `secureStore` is wired it fires at most once per device (reinstall-resilient
|
|
337
|
+
* on iOS via Keychain; Android re-fires after a reinstall, which is
|
|
338
|
+
* unavoidable post-GAID).
|
|
339
|
+
*
|
|
340
|
+
* @internal Exported for tests only — install tracking is automatic and this
|
|
341
|
+
* function is deliberately NOT on the `Advenue` facade. Do not call it from
|
|
342
|
+
* app code.
|
|
343
|
+
*/
|
|
344
|
+
declare function trackInstall(): Promise<void>;
|
|
160
345
|
|
|
161
|
-
export { Advenue, type MMKVLike, type RNAdvenueConfig, type SecureStoreLike, applyAppState, collectDeviceInfo, createMMKVStorage, createSecureStore, getAndroidNative, getIosNative, parseDirectLink, resolveAdvertisingId, resolveClipboardMatch };
|
|
346
|
+
export { Advenue, type AdvenueAndroidNativeModule, type AdvenueDeviceInfo, type AdvenueIosNativeModule, type InstallReferrerResult, type MMKVLike, type MetaInstallReferrerResult, type RNAdvenueConfig, type SecureStoreLike, type TrackingAuthorizationStatus, applyAppState, collectDeviceInfo, createMMKVStorage, createSecureStore, getAndroidNative, getIosNative, parseDirectLink, resolveAdvertisingId, resolveClipboardMatch, trackInstall };
|