@advenue/react-native 0.4.0 → 0.6.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.
@@ -0,0 +1,169 @@
1
+ // Native module contracts for the Expo modules that ship inside this package
2
+ // (ios/ and android/ directories, registered via expo-module.config.json).
3
+ // Formerly the public surface of @advenue/sdk-ios and @advenue/sdk-android —
4
+ // both retired when the native code moved in-package (single-install DX).
5
+
6
+ export interface InstallReferrerResult {
7
+ referrer: string;
8
+ /** Device-clock: referrerClickTimestampSeconds. */
9
+ clickTimestamp: number;
10
+ /** Device-clock: installBeginTimestampSeconds. */
11
+ installTimestamp: number;
12
+ /**
13
+ * Server-clock: referrerClickTimestampServerSeconds (G1 fraud trust —
14
+ * referrerTrust:'server'). 0 = unverified; absent on older native builds.
15
+ */
16
+ clickServerTimestamp?: number;
17
+ /** Server-clock: installBeginTimestampServerSeconds. 0 = unverified. */
18
+ installServerTimestamp?: number;
19
+ googlePlayInstant: boolean;
20
+ }
21
+
22
+ export interface MetaInstallReferrerResult {
23
+ installReferrer: string;
24
+ isClickThrough: boolean;
25
+ actualTimestamp: number;
26
+ /** Which Meta app served the referrer (e.g. com.facebook.katana). */
27
+ provider: string;
28
+ }
29
+
30
+ /**
31
+ * Device metadata for Meta CAPI `extinfo` (Task 3n). Structurally mirrors
32
+ * `DeviceInfo` from `@advenue/shared` — kept as a local subset type (rather
33
+ * than importing that package) so this native-module-only package stays
34
+ * dependency-free; the RN facade's `collectDeviceInfo()` merges it into the
35
+ * real `DeviceInfo` shape.
36
+ */
37
+ export interface AdvenueDeviceInfo {
38
+ model?: string;
39
+ locale?: string;
40
+ carrier?: string;
41
+ timezone?: string;
42
+ screenWidth?: number;
43
+ screenHeight?: number;
44
+ screenDensity?: number;
45
+ cpuCores?: number;
46
+ totalStorageGb?: number;
47
+ freeStorageGb?: number;
48
+ }
49
+
50
+ export interface AdvenueAndroidNativeModule {
51
+ /** Raw Play Install Referrer; parse with @advenue/install-referrer. */
52
+ getInstallReferrer(): Promise<InstallReferrerResult | null>;
53
+ /**
54
+ * Meta install referrer (null when no Facebook/Instagram app is installed);
55
+ * parse with parseMetaInstallReferrer from @advenue/install-referrer.
56
+ */
57
+ getMetaInstallReferrer(): Promise<MetaInstallReferrerResult | null>;
58
+ /** Google Advertising ID (GAID) + limit-ad-tracking flag; null when unavailable. */
59
+ getAdvertisingId(): Promise<{ id: string; limitAdTracking: boolean } | null>;
60
+ /** App Set ID — non-advertising, developer-scoped fallback id; null when unavailable. */
61
+ getAppSetId(): Promise<string | null>;
62
+ /**
63
+ * Play Integrity Standard API token (G3.1n).
64
+ *
65
+ * `requestHash` MUST be sha256_hex("<appId>:<deviceId>") — lowercase hex SHA-256
66
+ * of the literal string "<appId>:<deviceId>". The server's mapIntegrityVerdict
67
+ * re-derives the same string and compares it byte-for-byte.
68
+ *
69
+ * Rejects when:
70
+ * - ECONFIG: `io.advenue.INTEGRITY_CLOUD_PROJECT_NUMBER` meta-data is absent.
71
+ * - EUNSUPPORTED: Play Services unavailable or provider warming failed.
72
+ * - EINTEGRITY: Play returned an API-level error (network, quota, etc.).
73
+ *
74
+ * The JS bridge treats any rejection as "no attestation" and omits the token
75
+ * from the install event — rejection must never block the install track call.
76
+ */
77
+ getIntegrityToken(requestHash: string): Promise<string>;
78
+ /**
79
+ * Device metadata (model, locale, screen, cpu, storage, timezone) used to
80
+ * populate Meta CAPI `extinfo` (Task 3n). Synchronous, best-effort — the JS
81
+ * facade (`collectDeviceInfo`) treats a thrown error as "unavailable" and
82
+ * degrades to `{}` rather than blocking anything.
83
+ */
84
+ getDeviceInfo(): AdvenueDeviceInfo;
85
+ /**
86
+ * Built-in SDK storage (SharedPreferences `io.advenue.sdk`, MODE_PRIVATE) —
87
+ * the durable offline buffer + SDK state, so the app never supplies storage.
88
+ * Optional: absent on native builds predating this capability; the RN facade
89
+ * feature-detects and falls back to in-memory buffering. (No secure variant:
90
+ * Android has no reinstall-durable store — a reinstall legitimately re-fires
91
+ * the install, which the backend per-device window deduplicates.)
92
+ */
93
+ storageGetItem?(key: string): string | null;
94
+ storageSetItem?(key: string, value: string): void;
95
+ storageRemoveItem?(key: string): void;
96
+ /**
97
+ * Android SSAID (Settings.Secure.ANDROID_ID) — signing-key-scoped, stable
98
+ * across reinstalls. The RN facade reads it ONLY when no usable GAID exists
99
+ * (Adjust-style fallback) and it is used strictly as a first-party
100
+ * fraud/dedup + reinstall-detection signal, never for ad attribution (Play
101
+ * policy). Optional: absent on older native builds; feature-detected.
102
+ */
103
+ getAndroidId?(): string | null;
104
+ }
105
+
106
+ export type TrackingAuthorizationStatus = 'notDetermined' | 'restricted' | 'denied' | 'authorized';
107
+
108
+ export interface AdvenueIosNativeModule {
109
+ registerAppForAttribution(): void;
110
+ /**
111
+ * Conversion value: fine 0–63, coarse 'low'|'medium'|'high'. Updates the
112
+ * SKAN 4.0 postback, and on iOS 17.4+ the AdAttributionKit postback too.
113
+ */
114
+ updateConversionValue(fineValue: number, coarse: string, lockWindow: boolean): Promise<void>;
115
+ /** Apple Search Ads attribution token (resolve server-side). */
116
+ getAttributionToken(): Promise<string | null>;
117
+ /**
118
+ * Shows the ATT consent prompt; requires NSUserTrackingUsageDescription in
119
+ * the app's Info.plist. Resolves with the resulting status.
120
+ */
121
+ requestTrackingAuthorization(): Promise<TrackingAuthorizationStatus>;
122
+ getTrackingAuthorizationStatus(): TrackingAuthorizationStatus;
123
+ getAdvertisingId(): Promise<string | null>;
124
+ /** Vendor-scoped device id (IDFV) — available without ATT; a fallback anchor. */
125
+ getIdentifierForVendor(): string | null;
126
+ /** Clipboard match token (advmatch:<id>) for deterministic deferred deep linking; null if absent. */
127
+ getPasteboardMatchToken(): string | null;
128
+ /**
129
+ * G3.2n — App Attest. Generates (or reuses a keychain-cached) DCAppAttest
130
+ * key, computes clientDataHash = SHA-256(challenge), and calls
131
+ * DCAppAttestService.attestKey. Resolves { keyId, attestationObject } where
132
+ * attestationObject is a base64-encoded CBOR attestation for the server.
133
+ * Rejects with code EUNSUPPORTED on simulators (isSupported == false).
134
+ */
135
+ attestKey(challenge: string): Promise<{ keyId: string; attestationObject: string }>;
136
+ /**
137
+ * G3.3n — DeviceCheck. Calls DCDevice.current.generateToken to obtain the
138
+ * opaque base64 token that identifies this physical device to the Apple
139
+ * DeviceCheck API. The server queries/updates the persistent 2-bit per-device
140
+ * flag to detect reinstall abuse. Rejects with code EUNSUPPORTED on devices
141
+ * where DCDevice.current.isSupported is false (simulator, Catalyst, etc.).
142
+ */
143
+ getDeviceCheckToken(): Promise<string>;
144
+ /**
145
+ * Device metadata (model, locale, screen, cpu, storage, timezone) used to
146
+ * populate Meta CAPI `extinfo` (Task 3n). Synchronous, best-effort — the JS
147
+ * facade (`collectDeviceInfo`) treats a thrown error as "unavailable" and
148
+ * degrades to `{}` rather than blocking anything.
149
+ */
150
+ getDeviceInfo(): AdvenueDeviceInfo;
151
+ /**
152
+ * Built-in SDK storage (UserDefaults suite `io.advenue.sdk`) — the durable
153
+ * offline buffer + SDK state, so the app never supplies storage. Optional:
154
+ * absent on native builds predating this capability; the RN facade
155
+ * feature-detects and falls back to in-memory buffering.
156
+ */
157
+ storageGetItem?(key: string): string | null;
158
+ storageSetItem?(key: string, value: string): void;
159
+ storageRemoveItem?(key: string): void;
160
+ /**
161
+ * Built-in secure storage (Keychain, kSecAttrAccessibleAfterFirstUnlock,
162
+ * ThisDeviceOnly) — survives app reinstall, which is what makes the device
163
+ * identity and the install guard reinstall-resilient (Adjust-style).
164
+ * Optional: absent on older native builds; feature-detected.
165
+ */
166
+ secureGetItem?(key: string): string | null;
167
+ secureSetItem?(key: string, value: string): void;
168
+ secureRemoveItem?(key: string): void;
169
+ }
package/src/native.ts CHANGED
@@ -1,16 +1,22 @@
1
- import type { AdvenueAndroidNativeModule } from '@advenue/sdk-android';
2
- import type { AdvenueIosNativeModule } from '@advenue/sdk-ios';
1
+ import type { AdvenueAndroidNativeModule, AdvenueIosNativeModule } from './native-types';
3
2
 
4
3
  declare function require(id: string): unknown;
5
4
 
5
+ type ExpoModulesCore = {
6
+ requireNativeModule<T>(name: string): T;
7
+ };
8
+
6
9
  /**
7
- * Lazy access to the optional native modules. `requireNativeModule` throws at
8
- * import time when the native side isn't installed (Expo Go, web, missing
9
- * pods), so resolution happens inside try/catch — never at module scope.
10
+ * Lazy access to the native modules that ship inside this package (ios/ and
11
+ * android/, registered via expo-module.config.json). `requireNativeModule`
12
+ * throws when the native side isn't built (Expo Go, web, missing pods), so
13
+ * resolution happens inside try/catch — never at module scope.
14
+ * expo-modules-core is resolved from the consuming app's Expo install.
10
15
  */
11
16
  export function getIosNative(): AdvenueIosNativeModule | null {
12
17
  try {
13
- return (require('@advenue/sdk-ios') as { AdvenueIos: AdvenueIosNativeModule }).AdvenueIos;
18
+ const core = require('expo-modules-core') as ExpoModulesCore;
19
+ return core.requireNativeModule<AdvenueIosNativeModule>('AdvenueIos');
14
20
  } catch {
15
21
  return null;
16
22
  }
@@ -18,8 +24,8 @@ export function getIosNative(): AdvenueIosNativeModule | null {
18
24
 
19
25
  export function getAndroidNative(): AdvenueAndroidNativeModule | null {
20
26
  try {
21
- return (require('@advenue/sdk-android') as { AdvenueAndroid: AdvenueAndroidNativeModule })
22
- .AdvenueAndroid;
27
+ const core = require('expo-modules-core') as ExpoModulesCore;
28
+ return core.requireNativeModule<AdvenueAndroidNativeModule>('AdvenueAndroid');
23
29
  } catch {
24
30
  return null;
25
31
  }