@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.
- 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 +173 -8
- package/dist/index.js +10 -4
- package/expo-module.config.json +9 -0
- package/ios/AdvenueIos.podspec +20 -0
- package/ios/AdvenueIosModule.swift +461 -0
- package/package.json +9 -11
- package/src/deep-links.ts +5 -2
- package/src/index.ts +14 -3
- package/src/native-types.ts +169 -0
- package/src/native.ts +14 -8
|
@@ -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 '
|
|
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
|
|
8
|
-
*
|
|
9
|
-
*
|
|
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
|
-
|
|
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
|
-
|
|
22
|
-
|
|
27
|
+
const core = require('expo-modules-core') as ExpoModulesCore;
|
|
28
|
+
return core.requireNativeModule<AdvenueAndroidNativeModule>('AdvenueAndroid');
|
|
23
29
|
} catch {
|
|
24
30
|
return null;
|
|
25
31
|
}
|