react-native-shield-fraud-plugin 1.0.11 → 2.0.1

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.
@@ -2,27 +2,77 @@ package com.shieldfraudplugin;
2
2
 
3
3
  import androidx.annotation.NonNull;
4
4
 
5
- import com.facebook.react.ReactPackage;
5
+ import com.facebook.react.TurboReactPackage;
6
6
  import com.facebook.react.bridge.NativeModule;
7
7
  import com.facebook.react.bridge.ReactApplicationContext;
8
- import com.facebook.react.uimanager.ViewManager;
9
-
10
- import java.util.ArrayList;
11
- import java.util.Collections;
12
- import java.util.List;
13
-
14
- public class ShieldFraudPluginPackage implements ReactPackage {
15
- @NonNull
16
- @Override
17
- public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
18
- List<NativeModule> modules = new ArrayList<>();
19
- modules.add(new ShieldFraudPluginModule(reactContext));
20
- return modules;
21
- }
22
-
23
- @NonNull
24
- @Override
25
- public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
26
- return Collections.emptyList();
27
- }
8
+ import com.facebook.react.module.model.ReactModuleInfo;
9
+ import com.facebook.react.module.model.ReactModuleInfoProvider;
10
+
11
+ import java.util.HashMap;
12
+ import java.util.Map;
13
+
14
+ /**
15
+ * Package registration for ShieldFraudPlugin — works on both architectures.
16
+ *
17
+ * Why TurboReactPackage instead of ReactPackage
18
+ * ─────────────────────────────────────────────
19
+ * TurboReactPackage is a drop-in replacement for the legacy ReactPackage that
20
+ * adds support for Turbo Modules (New Architecture) while remaining fully
21
+ * backward-compatible with the Old Architecture bridge.
22
+ *
23
+ * On Old Architecture the isTurboModule flag in ReactModuleInfo is simply
24
+ * ignored and the module is loaded via the bridge as normal.
25
+ * On New Architecture the flag tells the runtime to resolve the module through
26
+ * the Turbo Module system (JSI) instead of the bridge.
27
+ *
28
+ * The isTurboModule flag is driven by BuildConfig.IS_NEW_ARCHITECTURE_ENABLED,
29
+ * which build.gradle sets to true/false based on the newArchEnabled property:
30
+ *
31
+ * buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED",
32
+ * isNewArchitectureEnabled().toString()
33
+ */
34
+ public class ShieldFraudPluginPackage extends TurboReactPackage {
35
+
36
+ // =========================================================================
37
+ // Module instantiation
38
+ // =========================================================================
39
+
40
+ @Override
41
+ public NativeModule getModule(@NonNull String name,
42
+ @NonNull ReactApplicationContext reactContext) {
43
+ if (name.equals(ShieldFraudPluginModule.NAME)) {
44
+ return new ShieldFraudPluginModule(reactContext);
45
+ }
46
+ return null;
47
+ }
48
+
49
+ // =========================================================================
50
+ // Module metadata
51
+ //
52
+ // ReactModuleInfoProvider returns the metadata the runtime needs to decide
53
+ // how to load the module:
54
+ // • Old Arch → isTurboModule=false → loaded via JS bridge
55
+ // • New Arch → isTurboModule=true → loaded via JSI (Turbo Module)
56
+ // =========================================================================
57
+
58
+ @Override
59
+ public ReactModuleInfoProvider getReactModuleInfoProvider() {
60
+ return () -> {
61
+ final boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
62
+ Map<String, ReactModuleInfo> moduleInfos = new HashMap<>();
63
+ moduleInfos.put(
64
+ ShieldFraudPluginModule.NAME,
65
+ new ReactModuleInfo(
66
+ ShieldFraudPluginModule.NAME, // name
67
+ ShieldFraudPluginModule.NAME, // className
68
+ false, // canOverrideExistingModule
69
+ false, // needsEagerInit
70
+ true, // hasConstants
71
+ false, // isCxxModule
72
+ isTurboModule // isTurboModule
73
+ )
74
+ );
75
+ return moduleInfos;
76
+ };
77
+ }
28
78
  }
@@ -0,0 +1,41 @@
1
+ package com.shieldfraudplugin;
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext;
4
+
5
+ /**
6
+ * New Architecture base class for ShieldFraudPluginModule.
7
+ *
8
+ * Selected by Gradle when newArchEnabled=true.
9
+ * Extends NativeShieldFraudPluginSpec — the abstract class generated by React
10
+ * Native's codegen from the TypeScript spec at src/NativeShieldFraudPlugin.ts.
11
+ *
12
+ * How the source-set swap works
13
+ * ─────────────────────────────
14
+ * build.gradle adds either src/oldarch or src/newarch to the Java source
15
+ * directories depending on the newArchEnabled project property:
16
+ *
17
+ * sourceSets {
18
+ * main {
19
+ * if (isNewArchitectureEnabled()) {
20
+ * java.srcDirs += ['src/newarch'] // this file is included
21
+ * } else {
22
+ * java.srcDirs += ['src/oldarch'] // this file is excluded
23
+ * }
24
+ * }
25
+ * }
26
+ *
27
+ * ShieldFraudPluginModule (in src/main/) always extends ShieldFraudPluginSpec,
28
+ * so it compiles correctly regardless of which shim is selected.
29
+ *
30
+ * NativeShieldFraudPluginSpec is generated at build time by the React Native
31
+ * Gradle plugin (com.facebook.react) when New Architecture is enabled.
32
+ * It declares all methods from the TypeScript spec as abstract — this shim
33
+ * exists purely to bridge the inheritance chain so ShieldFraudPluginModule
34
+ * does not need to import the codegen class directly.
35
+ */
36
+ abstract class ShieldFraudPluginSpec extends NativeShieldFraudPluginSpec {
37
+
38
+ protected ShieldFraudPluginSpec(ReactApplicationContext context) {
39
+ super(context);
40
+ }
41
+ }
@@ -0,0 +1,36 @@
1
+ package com.shieldfraudplugin;
2
+
3
+ import com.facebook.react.bridge.ReactApplicationContext;
4
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
5
+
6
+ /**
7
+ * Old Architecture base class for ShieldFraudPluginModule.
8
+ *
9
+ * Selected by Gradle when newArchEnabled=false (the default).
10
+ * Extends ReactContextBaseJavaModule — the standard base class for modules
11
+ * that communicate with JS over the legacy bridge.
12
+ *
13
+ * How the source-set swap works
14
+ * ─────────────────────────────
15
+ * build.gradle adds either src/oldarch or src/newarch to the Java source
16
+ * directories depending on the newArchEnabled project property:
17
+ *
18
+ * sourceSets {
19
+ * main {
20
+ * if (isNewArchitectureEnabled()) {
21
+ * java.srcDirs += ['src/newarch'] // this file is excluded
22
+ * } else {
23
+ * java.srcDirs += ['src/oldarch'] // this file is included
24
+ * }
25
+ * }
26
+ * }
27
+ *
28
+ * ShieldFraudPluginModule (in src/main/) always extends ShieldFraudPluginSpec,
29
+ * so it compiles correctly regardless of which shim is selected.
30
+ */
31
+ abstract class ShieldFraudPluginSpec extends ReactContextBaseJavaModule {
32
+
33
+ protected ShieldFraudPluginSpec(ReactApplicationContext context) {
34
+ super(context);
35
+ }
36
+ }
@@ -1,13 +1,22 @@
1
1
 
2
2
  #ifdef RCT_NEW_ARCH_ENABLED
3
+ // New Architecture: conform to the codegen-generated spec protocol.
4
+ // RCTEventEmitter is still used as the base so that sendEventWithName: works.
5
+ #import <React/RCTEventEmitter.h>
3
6
  #import "RNShieldFraudPluginSpec.h"
4
7
 
5
- @interface ShieldFraudPlugin : NSObject <NativeShieldFraudPluginSpec>
8
+ // Forward-declare the protocol — the full definition is imported in the .mm file.
9
+ // A forward declaration is sufficient for the @interface conformance declaration.
10
+ @protocol DeviceShieldCallback;
11
+
12
+ @interface ShieldFraudPlugin : RCTEventEmitter <NativeShieldFraudPluginSpec, DeviceShieldCallback>
6
13
  #else
14
+ // Old Architecture: standard bridge module + event emitter.
7
15
  #import <React/RCTBridgeModule.h>
8
16
  #import <React/RCTEventEmitter.h>
9
17
 
10
- @import ShieldFraud;
18
+ // Forward-declare the protocol — full definition imported in the .mm file.
19
+ @protocol DeviceShieldCallback;
11
20
 
12
21
  @interface ShieldFraudPlugin : RCTEventEmitter <RCTBridgeModule, DeviceShieldCallback>
13
22
  #endif
@@ -0,0 +1,289 @@
1
+ #import "ShieldFraudPlugin.h"
2
+
3
+ // Import the auto-generated Swift→ObjC header.
4
+ // This exposes all Swift-exported types (Configuration, Shield, BlockedDialog,
5
+ // LogLevel, Environment, ShieldCrossPlatformHelper, DeviceShieldCallback, …)
6
+ // without requiring Clang module syntax (@import), which fails in Obj-C++ files
7
+ // when C++ modules are not enabled (e.g. when the New Architecture codegen
8
+ // headers are included and the file is compiled as Obj-C++).
9
+ #import <ShieldFraud/ShieldFraud-Swift.h>
10
+
11
+ @implementation ShieldFraudPlugin
12
+
13
+ static BOOL isShieldInitialized = NO;
14
+
15
+ RCT_EXPORT_MODULE();
16
+
17
+ // =============================================================================
18
+ // MARK: - Shared methods (Old Architecture & New Architecture)
19
+ //
20
+ // These methods have identical signatures in both architectures.
21
+ // RCT_EXPORT_METHOD registers them with the bridge for Old Arch, and the
22
+ // matching Obj-C selectors satisfy the codegen protocol for New Arch.
23
+ // =============================================================================
24
+
25
+ // Cross-platform SDK metadata (React Native wrapper version / name)
26
+ RCT_EXPORT_METHOD(setCrossPlatformParameters:(NSString *)crossPlatformName
27
+ crossPlatformVersion:(NSString *)crossPlatformVersion)
28
+ {
29
+ ShieldCrossPlatformParams *params = [[ShieldCrossPlatformParams alloc]
30
+ initWithName:crossPlatformName
31
+ version:crossPlatformVersion];
32
+ [ShieldCrossPlatformHelper setCrossPlatformParameters:params];
33
+ }
34
+
35
+ // Retrieve the most-recently-computed device result
36
+ RCT_EXPORT_METHOD(getLatestDeviceResult:(RCTResponseSenderBlock)successCallback
37
+ errorCallback:(RCTResponseSenderBlock)errorCallback)
38
+ {
39
+ NSDictionary<NSString *, id> *result = [[Shield shared] getLatestDeviceResult];
40
+ if (result != NULL) {
41
+ successCallback(@[result]);
42
+ return;
43
+ }
44
+
45
+ NSError *error = [[Shield shared] getErrorResponse];
46
+ if (error != NULL) {
47
+ errorCallback(@[[error localizedDescription]]);
48
+ return;
49
+ }
50
+
51
+ errorCallback(@[@"No device result available yet."]);
52
+ }
53
+
54
+ // Subscribe to real-time device-result state changes
55
+ RCT_EXPORT_METHOD(setDeviceResultStateListener)
56
+ {
57
+ double delayInSeconds = 1.5;
58
+ dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW,
59
+ (int64_t)(delayInSeconds * NSEC_PER_SEC));
60
+ dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
61
+ [[Shield shared] setDeviceResultStateListener:^{
62
+ [self sendEventWithName:@"device_result_state"
63
+ body:@{@"status": @"isSDKReady"}];
64
+ }];
65
+ });
66
+ }
67
+
68
+ // Attach arbitrary screen-level attributes
69
+ RCT_EXPORT_METHOD(sendAttributes:(NSString *)screenName
70
+ data:(NSDictionary *)data)
71
+ {
72
+ [[Shield shared] sendAttributesWithScreenName:screenName data:data];
73
+ }
74
+
75
+ RCT_EXPORT_METHOD(sendAttributesWithCallback:(NSString *)screenName
76
+ data:(NSDictionary *)data
77
+ successCallback:(RCTResponseSenderBlock)successCallback
78
+ errorCallback:(RCTResponseSenderBlock)errorCallback)
79
+ {
80
+ [[Shield shared] sendAttributesWithScreenName:screenName
81
+ data:data
82
+ :^(BOOL success, NSError *error) {
83
+ dispatch_async(dispatch_get_main_queue(), ^{
84
+ if (success) {
85
+ successCallback(@[@(YES)]);
86
+ return;
87
+ }
88
+
89
+ NSString *errorMessage = error != nil
90
+ ? [error localizedDescription]
91
+ : @"Failed to send attributes.";
92
+ errorCallback(@[errorMessage]);
93
+ });
94
+ }];
95
+ }
96
+
97
+ // Trigger a device signature computation for a given screen name.
98
+ // The completionHandler fires when the SDK is done; results and errors
99
+ // are read back from getLatestDeviceResult / getErrorResponse.
100
+ RCT_EXPORT_METHOD(sendDeviceSignature:(NSString *)screenName
101
+ successCallback:(RCTResponseSenderBlock)successCallback
102
+ errorCallback:(RCTResponseSenderBlock)errorCallback)
103
+ {
104
+ [[Shield shared] sendDeviceSignatureWithScreenName:screenName
105
+ completionHandler:^{
106
+ dispatch_async(dispatch_get_main_queue(), ^{
107
+ NSDictionary<NSString *, id> *deviceResult = [[Shield shared] getLatestDeviceResult];
108
+ if (deviceResult != nil) {
109
+ successCallback(@[deviceResult]);
110
+ return;
111
+ }
112
+
113
+ NSError *error = [[Shield shared] getErrorResponse];
114
+ if (error != nil) {
115
+ errorCallback(@[[error localizedDescription]]);
116
+ return;
117
+ }
118
+
119
+ errorCallback(@[@"No device result available."]);
120
+ });
121
+ }];
122
+ }
123
+
124
+ // RCTEventEmitter — declare the events this module can emit
125
+ - (NSArray<NSString *> *)supportedEvents
126
+ {
127
+ return @[@"success", @"error", @"device_result_state"];
128
+ }
129
+
130
+ // RCTEventEmitter — required overrides (no-op wrappers keep the base class happy)
131
+ - (void)addListener:(NSString *)eventName
132
+ {
133
+ [super addListener:eventName];
134
+ }
135
+
136
+ - (void)removeListeners:(double)count
137
+ {
138
+ [super removeListeners:count];
139
+ }
140
+
141
+ // DeviceShieldCallback delegate — forwarded as JS events
142
+ - (void)didErrorWithError:(NSError *)error
143
+ {
144
+ [self sendEventWithName:@"error" body:[error localizedDescription]];
145
+ }
146
+
147
+ - (void)didSuccessWithResult:(NSDictionary<NSString *, id> *)result
148
+ {
149
+ [self sendEventWithName:@"success" body:result];
150
+ }
151
+
152
+
153
+ // =============================================================================
154
+ // MARK: - Architecture-specific methods
155
+ // =============================================================================
156
+
157
+ #ifdef RCT_NEW_ARCH_ENABLED
158
+
159
+ // -----------------------------------------------------------------------------
160
+ // New Architecture (Turbo Modules / JSI)
161
+ //
162
+ // Methods are implemented as plain Obj-C methods to directly satisfy the
163
+ // codegen-generated NativeShieldFraudPluginSpec protocol.
164
+ //
165
+ // Key differences from Old Arch:
166
+ // • initShield — logLevel/environmentInfo are `double` (JS numbers are
167
+ // always doubles); resolve/reject blocks are added for the
168
+ // Promise<void> return type declared in the TS spec.
169
+ // • getSessionId / isShieldInitialized — synchronous return values are
170
+ // supported natively by JSI (no blocking-synchronous macro).
171
+ // • isShieldInitialized — protocol requires NSNumber* so JSI can marshal
172
+ // the boolean; returning plain BOOL would be a type mismatch.
173
+ // • getTurboModule: — wires this Obj-C class into the JSI runtime.
174
+ // -----------------------------------------------------------------------------
175
+
176
+ - (void)initShield:(NSString *)siteID
177
+ secretKey:(NSString *)secretKey
178
+ isOptimizedListener:(BOOL)isOptimizedListener
179
+ blockedDialog:(NSDictionary * _Nullable)blockedDialog
180
+ logLevel:(double)logLevel
181
+ environmentInfo:(double)environmentInfo
182
+ blockScreenRecording:(BOOL)blockScreenRecording
183
+ resolve:(RCTPromiseResolveBlock)resolve
184
+ reject:(RCTPromiseRejectBlock)reject
185
+ {
186
+ if (!isShieldInitialized) {
187
+ Configuration *config = [[Configuration alloc] initWithSiteId:siteID
188
+ secretKey:secretKey];
189
+ if (isOptimizedListener) {
190
+ config.deviceShieldCallback = self;
191
+ }
192
+
193
+ if (blockedDialog != nil) {
194
+ NSString *title = [blockedDialog objectForKey:@"title"];
195
+ NSString *body = [blockedDialog objectForKey:@"body"];
196
+ config.defaultBlockedDialog = [[BlockedDialog alloc] initWithTitle:title
197
+ body:body];
198
+ }
199
+
200
+ // JS numbers arrive as double; cast explicitly to Swift-bridged enum types.
201
+ config.logLevel = (LogLevel)(NSInteger)logLevel;
202
+ config.environment = (Environment)(NSInteger)environmentInfo;
203
+
204
+ [Shield setUpWith:config];
205
+ isShieldInitialized = YES;
206
+ }
207
+ resolve(nil);
208
+ }
209
+
210
+ - (NSString *)getSessionId
211
+ {
212
+ return [[Shield shared] sessionId];
213
+ }
214
+
215
+ - (NSNumber *)isShieldInitialized
216
+ {
217
+ return @(isShieldInitialized);
218
+ }
219
+
220
+ // Wires this Obj-C class into the JSI runtime.
221
+ // The generated class name follows the codegenConfig "name" in package.json:
222
+ // "RNShieldFraudPluginSpec" → NativeShieldFraudPluginSpecJSI
223
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
224
+ (const facebook::react::ObjCTurboModule::InitParams &)params
225
+ {
226
+ return std::make_shared<facebook::react::NativeShieldFraudPluginSpecJSI>(params);
227
+ }
228
+
229
+ #else
230
+
231
+ // -----------------------------------------------------------------------------
232
+ // Old Architecture (Bridge)
233
+ //
234
+ // RCT_EXPORT_METHOD — registers void-return methods with the JS bridge.
235
+ // RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD — bridge-only macro for synchronous
236
+ // return values; has no JSI equivalent and must stay inside #else.
237
+ //
238
+ // Key differences from New Arch:
239
+ // • initShield — logLevel/environmentInfo are NSInteger (bridge coerces
240
+ // from NSNumber); no resolve/reject (bridge wraps the void
241
+ // return automatically).
242
+ // • getSessionId / isShieldInitialized — must use the blocking-synchronous
243
+ // macro so the bridge returns the value to JS synchronously.
244
+ // -----------------------------------------------------------------------------
245
+
246
+ RCT_EXPORT_METHOD(initShield:(NSString *)siteID
247
+ secretKey:(NSString *)secretKey
248
+ isOptimizedListener:(BOOL)isOptimizedListener
249
+ blockedDialog:(NSDictionary *)blockedDialog
250
+ logLevel:(NSInteger)logLevel
251
+ environmentInfo:(NSInteger)environmentInfo
252
+ blockScreenRecording:(BOOL)blockScreenRecording)
253
+ {
254
+ if (!isShieldInitialized) {
255
+ Configuration *config = [[Configuration alloc] initWithSiteId:siteID
256
+ secretKey:secretKey];
257
+ if (isOptimizedListener) {
258
+ config.deviceShieldCallback = self;
259
+ }
260
+
261
+ if (blockedDialog != nil) {
262
+ NSString *title = [blockedDialog objectForKey:@"title"];
263
+ NSString *body = [blockedDialog objectForKey:@"body"];
264
+ config.defaultBlockedDialog = [[BlockedDialog alloc] initWithTitle:title
265
+ body:body];
266
+ }
267
+
268
+ // Cast NSInteger to Swift-bridged enum types explicitly.
269
+ config.logLevel = (LogLevel)logLevel;
270
+ config.environment = (Environment)environmentInfo;
271
+
272
+ [Shield setUpWith:config];
273
+ isShieldInitialized = YES;
274
+ }
275
+ }
276
+
277
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(getSessionId)
278
+ {
279
+ return [[Shield shared] sessionId];
280
+ }
281
+
282
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isShieldInitialized)
283
+ {
284
+ return @(isShieldInitialized);
285
+ }
286
+
287
+ #endif // RCT_NEW_ARCH_ENABLED
288
+
289
+ @end
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _reactNative = require("react-native");
8
+ /**
9
+ * TypeScript spec for the ShieldFraudPlugin Turbo Module.
10
+ * This file is used by React Native codegen to auto-generate
11
+ * native interface code for both iOS and Android.
12
+ */
13
+ var _default = _reactNative.TurboModuleRegistry.getEnforcing('ShieldFraudPlugin');
14
+ exports.default = _default;
15
+ //# sourceMappingURL=NativeShieldFraudPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"names":["_reactNative","require","_default","TurboModuleRegistry","getEnforcing","exports","default"],"sourceRoot":"../../src","sources":["NativeShieldFraudPlugin.ts"],"mappings":";;;;;;AACA,IAAAA,YAAA,GAAAC,OAAA;AAEA;AACA;AACA;AACA;AACA;AAJA,IAAAC,QAAA,GAiFeC,gCAAmB,CAACC,YAAY,CAAO,mBAAmB,CAAC;AAAAC,OAAA,CAAAC,OAAA,GAAAJ,QAAA"}
@@ -5,10 +5,17 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = exports.LogLevel = exports.EnvironmentInfo = void 0;
7
7
  var _reactNative = require("react-native");
8
+ /**
9
+ * Resolve the native module through TurboModuleRegistry (New Architecture)
10
+ * with a fallback to NativeModules bridge (Old Architecture).
11
+ */
12
+ const ShieldFraudPluginNativeModule = _reactNative.TurboModuleRegistry.get("ShieldFraudPlugin") ?? _reactNative.NativeModules.ShieldFraudPlugin;
13
+
8
14
  /**
9
15
  * Enum representing the log levels for ShieldFraud.
10
16
  */
11
17
  let LogLevel = /*#__PURE__*/function (LogLevel) {
18
+ LogLevel[LogLevel["LogLevelVerbose"] = 4] = "LogLevelVerbose";
12
19
  LogLevel[LogLevel["LogLevelDebug"] = 3] = "LogLevelDebug";
13
20
  LogLevel[LogLevel["LogLevelInfo"] = 2] = "LogLevelInfo";
14
21
  LogLevel[LogLevel["LogLevelNone"] = 1] = "LogLevelNone";
@@ -21,9 +28,9 @@ exports.LogLevel = LogLevel;
21
28
  let EnvironmentInfo = /*#__PURE__*/function (EnvironmentInfo) {
22
29
  EnvironmentInfo[EnvironmentInfo["EnvironmentProd"] = 0] = "EnvironmentProd";
23
30
  EnvironmentInfo[EnvironmentInfo["EnvironmentDev"] = 1] = "EnvironmentDev";
24
- EnvironmentInfo[EnvironmentInfo["EnvironmentStag"] = 2] = "EnvironmentStag";
31
+ EnvironmentInfo[EnvironmentInfo["EnvironmentStaging"] = 2] = "EnvironmentStaging";
25
32
  return EnvironmentInfo;
26
- }({});
33
+ }({}); // Environment.STAGING
27
34
  /**
28
35
  * Configuration object for initializing ShieldFraud.
29
36
  */
@@ -45,8 +52,10 @@ exports.EnvironmentInfo = EnvironmentInfo;
45
52
  class ShieldFraud {
46
53
  /**
47
54
  * The native module for accessing the ShieldFraudPlugin.
55
+ * Resolved via TurboModuleRegistry on New Architecture, with
56
+ * a NativeModules bridge fallback for Old Architecture.
48
57
  */
49
- static PlatformWrapper = _reactNative.NativeModules.ShieldFraudPlugin;
58
+ static PlatformWrapper = ShieldFraudPluginNativeModule;
50
59
 
51
60
  /**
52
61
  * The event emitter for listening to success and error events.
@@ -71,8 +80,13 @@ class ShieldFraud {
71
80
  // Set cross-platform parameters internally (React Native and version from package.json)
72
81
  ShieldFraud.setCrossPlatformParameters();
73
82
 
83
+ // blockScreenRecording is Android-only; iOS native ignores the value.
84
+ // Always send a real boolean — the Old Arch bridge cannot handle null
85
+ // for boolean parameters (causes NPE in ReadableNativeArray.getBoolean).
86
+ const blockScreenRecording = _reactNative.Platform.OS === "android" ? config.blockScreenRecording ?? false : false;
87
+
74
88
  // Call the native method to initialize ShieldFraud with the provided configuration.
75
- await ShieldFraud.PlatformWrapper.initShield(config.siteID, config.secretKey, isOptimizedListener, config.blockedDialog, logLevel, environmentInfo);
89
+ await ShieldFraud.PlatformWrapper.initShield(config.siteID, config.secretKey, isOptimizedListener, config.blockedDialog ?? null, logLevel, environmentInfo, blockScreenRecording);
76
90
  if (isOptimizedListener) {
77
91
  // Set up listeners for success and error events if callbacks are provided.
78
92
  ShieldFraud.listeners(callbacks);
@@ -85,7 +99,7 @@ class ShieldFraud {
85
99
  */
86
100
  static setCrossPlatformParameters() {
87
101
  const crossPlatformName = "react-native-shield-fraud-plugin";
88
- const crossPlatformVersion = "1.0.11";
102
+ const crossPlatformVersion = "2.0.1";
89
103
  ShieldFraud.PlatformWrapper.setCrossPlatformParameters(crossPlatformName, crossPlatformVersion);
90
104
  }
91
105
 
@@ -129,12 +143,21 @@ class ShieldFraud {
129
143
  }
130
144
 
131
145
  /**
132
- * Checks if the ShieldFraud SDK is ready and invokes the provided callback with the readiness state.
146
+ * Checks if the ShieldFraud SDK is ready and invokes the provided callback
147
+ * with the readiness state.
148
+ *
149
+ * On Android, readiness is approximated by the native initialization state
150
+ * to preserve backward compatibility without reporting ready before init.
133
151
  *
134
152
  * @param callback - A callback function to be invoked with the readiness state.
135
- * - `isReady` (boolean): A boolean value indicating whether the ShieldFraud SDK is ready.
153
+ * - `isReady` (boolean): true when the SDK has produced a device result.
136
154
  */
137
155
  static async isSDKready(callback) {
156
+ if (_reactNative.Platform.OS === "android") {
157
+ const isInitialized = await this.isShieldInitialized();
158
+ callback(isInitialized);
159
+ return;
160
+ }
138
161
  try {
139
162
  // Adding a timeout of 100 milliseconds
140
163
  await new Promise(resolve => setTimeout(resolve, 100));
@@ -151,6 +174,8 @@ class ShieldFraud {
151
174
  }
152
175
  };
153
176
  ShieldFraud.eventEmitter.addListener("device_result_state", deviceResultListener);
177
+
178
+ // Trigger the SDK subscription — iOS 1.x requires this explicit call.
154
179
  ShieldFraud.PlatformWrapper.setDeviceResultStateListener();
155
180
  } catch (error) {
156
181
  console.error("An error occurred:", error);
@@ -168,6 +193,23 @@ class ShieldFraud {
168
193
  ShieldFraud.PlatformWrapper.sendAttributes(screenName, data);
169
194
  }
170
195
 
196
+ /**
197
+ * Sends attributes and resolves with `true` when the native SDK confirms success.
198
+ *
199
+ * @param screenName - The name of the screen.
200
+ * @param data - The attribute data object.
201
+ * @returns A Promise that resolves to true on success and rejects on error.
202
+ */
203
+ static sendAttributesWithCallback(screenName, data) {
204
+ return new Promise((resolve, reject) => {
205
+ ShieldFraud.PlatformWrapper.sendAttributesWithCallback(screenName, data, result => {
206
+ resolve(!!result);
207
+ }, error => {
208
+ reject(error);
209
+ });
210
+ });
211
+ }
212
+
171
213
  /**
172
214
  * Retrieves the latest device result from the ShieldFraud plugin.
173
215
  *
@@ -176,10 +218,26 @@ class ShieldFraud {
176
218
  static getLatestDeviceResult() {
177
219
  return new Promise((resolve, reject) => {
178
220
  ShieldFraud.PlatformWrapper.getLatestDeviceResult(result => {
179
- // Handle success with the result object
180
221
  resolve(result);
181
222
  }, error => {
182
- // Handle error with the error object
223
+ reject(error);
224
+ });
225
+ });
226
+ }
227
+
228
+ /**
229
+ * Triggers a device signature computation for a given screen name.
230
+ * On success, resolves with the latest device result object.
231
+ * On failure, rejects with the error message.
232
+ *
233
+ * @param screenName - The name of the screen triggering the signature.
234
+ * @returns A Promise that resolves with the device result or rejects with an error.
235
+ */
236
+ static sendDeviceSignature(screenName) {
237
+ return new Promise((resolve, reject) => {
238
+ ShieldFraud.PlatformWrapper.sendDeviceSignature(screenName, result => {
239
+ resolve(result);
240
+ }, error => {
183
241
  reject(error);
184
242
  });
185
243
  });