@explorins/pers-sdk-react-native 2.1.13 → 2.1.14-beta.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 CHANGED
@@ -48,15 +48,110 @@ The SDK automatically installs the following native libraries. **You must rebuil
48
48
  npm install react-native-url-polyfill
49
49
  ```
50
50
 
51
+ ### Metro Configuration (Required)
52
+
53
+ The PERS SDK uses subpath exports (`@explorins/pers-sdk/core`, etc.) which require Metro to be configured. Add to your `metro.config.js`:
54
+
55
+ ```javascript
56
+ const { getDefaultConfig } = require('expo/metro-config');
57
+ // or for bare RN: const { getDefaultConfig } = require('@react-native/metro-config');
58
+
59
+ const config = getDefaultConfig(__dirname);
60
+
61
+ // REQUIRED: Enable package exports for PERS SDK subpath imports
62
+ config.resolver.unstable_enablePackageExports = true;
63
+
64
+ module.exports = config;
65
+ ```
66
+
67
+ ---
68
+
69
+ ## ⚠️ Android Architecture Requirements
70
+
71
+ **The SDK requires React Native New Architecture** starting from v2.1.x.
72
+
73
+ ### Why?
74
+
75
+ `react-native-quick-crypto` v1.0+ (used for high-performance cryptographic operations) uses [Nitro Modules](https://github.com/margelo/nitro), which require New Architecture.
76
+
77
+ ### Quick Check
78
+
79
+ If you see errors like:
80
+ ```
81
+ NitroModulesProxy.createHybridObject(...) threw an unknown std::runtime_error
82
+ ```
83
+
84
+ Your app is running with **Old Architecture** (`newArchEnabled=false`).
85
+
86
+ ### Solution 1: Enable New Architecture (Recommended)
87
+
88
+ React Native 0.76+ has stable New Architecture support. Enable it in `android/gradle.properties`:
89
+
90
+ ```properties
91
+ # android/gradle.properties
92
+
93
+ # Use this property to enable support to the new architecture.
94
+ newArchEnabled=true
95
+
96
+ # Use this property to enable or disable the Hermes JS engine.
97
+ hermesEnabled=true
98
+ ```
99
+
100
+ Then clean and rebuild:
101
+
102
+ ```bash
103
+ cd android && ./gradlew clean && cd ..
104
+ npx react-native start --reset-cache
105
+ npx react-native run-android
106
+ ```
107
+
108
+ > **Reference**: See the [VQ Demo App's gradle.properties](https://github.com/explorins/vq-pers-integration-demo/blob/main/android/gradle.properties) for a working configuration with Expo SDK 54 and React Native 0.81.5.
109
+
110
+ ### Solution 2: Downgrade quick-crypto (For Old Architecture)
111
+
112
+ If you must stay on Old Architecture, pin to v0.7.x:
113
+
114
+ ```json
115
+ {
116
+ "resolutions": {
117
+ "react-native-quick-crypto": "0.7.17"
118
+ }
119
+ }
120
+ ```
121
+
122
+ Or for npm (in `package.json`):
123
+
124
+ ```json
125
+ {
126
+ "overrides": {
127
+ "react-native-quick-crypto": "0.7.17"
128
+ }
129
+ }
130
+ ```
131
+
132
+ ### Compatibility Matrix
133
+
134
+ | RN Version | Architecture | quick-crypto | Status |
135
+ |------------|--------------|--------------|--------|
136
+ | 0.76+ | New (`newArchEnabled=true`) | 1.0.6+ | ✅ Recommended |
137
+ | 0.76+ | Old (`newArchEnabled=false`) | 0.7.17 | ⚠️ Requires downgrade |
138
+ | < 0.76 | Old | 0.7.x | ⚠️ Use older quick-crypto |
139
+
140
+ > **See [Android Compatibility FAQ](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/docs/ANDROID_COMPATIBILITY_FAQ.md)** for detailed troubleshooting.
141
+
142
+ ---
51
143
 
52
144
  ## Critical Setup Requirement: Passkeys
53
145
 
54
- To enable Passkey authentication (WebAuthn) on iOS and Android, you **must** complete the setup in **[REACT_NATIVE_PASSKEY_SETUP.md](./REACT_NATIVE_PASSKEY_SETUP.md)**.
146
+ To enable Passkey authentication (WebAuthn) on iOS and Android, you **must**:
147
+
148
+ 1. **Register your app with PERS backend** - Contact **support@explorins.com** with:
149
+ - iOS: Bundle ID + Apple Team ID
150
+ - Android: Package Name + SHA-256 fingerprint
151
+
152
+ 2. **Configure native files** - See [Passkey Setup Guide](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/REACT_NATIVE_PASSKEY_SETUP.md)
55
153
 
56
- This includes:
57
- - Registering your app with the PERS backend (required for OS trust)
58
- - Native configuration (Info.plist, AndroidManifest.xml)
59
- - Expo/development build setup
154
+ 3. **For Expo**: Use development builds (`npx expo run:android`), not Expo Go
60
155
 
61
156
  ## Quick Start
62
157
 
@@ -1027,16 +1122,15 @@ const tokens = (await getTokens()).data;
1027
1122
 
1028
1123
  ## Documentation
1029
1124
 
1030
- ### Core Guides
1031
- - **[AUTH_STATE_HANDLING.md](./docs/AUTH_STATE_HANDLING.md)** - Comprehensive guide for handling authentication state changes
1032
- - Pattern examples for observing `isAuthenticated` state
1033
- - Custom UI for session expiration
1034
- - Platform-specific details (iOS Keychain, Android Keystore, Web)
1035
- - Best practices for auth state observation
1125
+ All documentation is available on GitHub:
1036
1126
 
1037
- ### Setup & Configuration
1038
- - **[REACT_NATIVE_PASSKEY_SETUP.md](./REACT_NATIVE_PASSKEY_SETUP.md)** - Required setup for WebAuthn/Passkey authentication
1039
- - **[DPOP_IMPLEMENTATION_GUIDE.md](./DPOP_IMPLEMENTATION_GUIDE.md)** - DPoP security implementation details
1127
+ | Guide | Description |
1128
+ |-------|-------------|
1129
+ | [Quick Setup Guide](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/docs/QUICK_SETUP_GUIDE.md) | Android + Passkey setup in one page |
1130
+ | [Passkey Setup](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/REACT_NATIVE_PASSKEY_SETUP.md) | WebAuthn/Passkey configuration |
1131
+ | [Android Compatibility](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/docs/ANDROID_COMPATIBILITY_FAQ.md) | New Architecture troubleshooting |
1132
+ | [Auth State Handling](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/docs/AUTH_STATE_HANDLING.md) | Session management patterns |
1133
+ | [Changelog](https://github.com/eXplorins/pers-sdk/blob/main/packages/pers-sdk-react-native/CHANGELOG.md) | Version history |
1040
1134
 
1041
1135
  ---
1042
1136
 
@@ -7,6 +7,8 @@ export type { CampaignClaimFilters } from '@explorins/pers-sdk/campaign';
7
7
  export interface GetCampaignsOptions {
8
8
  /** Filter by tag */
9
9
  tag?: string;
10
+ /** Free text search across name and description (case-insensitive) */
11
+ search?: string;
10
12
  /** Filter by business ID */
11
13
  businessId?: string;
12
14
  /** Page number (1-indexed) */
@@ -1 +1 @@
1
- {"version":3,"file":"useCampaigns.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaigns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,uBAAuB,EACvB,SAAS,EAEV,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGzE,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC;IAC5C,iBAAiB;IACjB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACrC;AAED,eAAO,MAAM,YAAY;mCA6BX,mBAAmB,KAC5B,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCAgC/B,MAAM,YACR,uBAAuB,EAAE,KAClC,QAAQ,WAAW,GAAG,IAAI,CAAC;6BAuEoB,uBAAuB,KAAG,QAAQ,gBAAgB,GAAG,IAAI,CAAC;8BAmCzD;QACjD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,4BAA4B,EAAE,CAAC;KAC1C,KAAG,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;+BAkBD,QAAQ,qBAAqB,kBAAkB,CAAC,CAAC;gCA0CvF,mBAAmB,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KACnD,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCA+BjC,oBAAoB,YACpB,4BAA4B,EAAE,KACvC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;wCAsBxC,MAAM,YACJ,4BAA4B,EAAE,KACvC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;gDAsBpC,MAAM,YACR,4BAA4B,EAAE,KACvC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;sCA4CpC,MAAM,mBACD,MAAM,KACtB,QAAQ,WAAW,CAAC;sCA4BT,MAAM,mBACD,MAAM,KACtB,QAAQ,WAAW,CAAC;;CA+BxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
1
+ {"version":3,"file":"useCampaigns.d.ts","sourceRoot":"","sources":["../../src/hooks/useCampaigns.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,uBAAuB,EACvB,WAAW,EACX,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EACpB,4BAA4B,EAC5B,uBAAuB,EACvB,SAAS,EAEV,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAGzE,YAAY,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEzE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sEAAsE;IACtE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,WAAW,CAAC;IAC5C,iBAAiB;IACjB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,uBAAuB,EAAE,CAAC;CACrC;AAED,eAAO,MAAM,YAAY;mCA6BX,mBAAmB,KAC5B,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCAgC/B,MAAM,YACR,uBAAuB,EAAE,KAClC,QAAQ,WAAW,GAAG,IAAI,CAAC;6BAuEoB,uBAAuB,KAAG,QAAQ,gBAAgB,GAAG,IAAI,CAAC;8BAmCzD;QACjD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,OAAO,CAAC,EAAE,4BAA4B,EAAE,CAAC;KAC1C,KAAG,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;+BAkBD,QAAQ,qBAAqB,kBAAkB,CAAC,CAAC;gCA0CvF,mBAAmB,GAAG;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KACnD,QAAQ,qBAAqB,WAAW,CAAC,CAAC;kCA+BjC,oBAAoB,YACpB,4BAA4B,EAAE,KACvC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;wCAsBxC,MAAM,YACJ,4BAA4B,EAAE,KACvC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;gDAsBpC,MAAM,YACR,4BAA4B,EAAE,KACvC,QAAQ,qBAAqB,gBAAgB,CAAC,CAAC;sCA4CpC,MAAM,mBACD,MAAM,KACtB,QAAQ,WAAW,CAAC;sCA4BT,MAAM,mBACD,MAAM,KACtB,QAAQ,WAAW,CAAC;;CA+BxB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC"}
@@ -1,12 +1,27 @@
1
1
  import { OnStatusUpdateFn } from './useTransactionSigner';
2
- import type { RedemptionCreateRequestDTO, RedemptionDTO, RedemptionRedeemDTO, RedemptionRedeemRequestResponseDTO, RedemptionTypeDTO, PaginatedResponseDTO, RedemptionRedeemIncludeRelation, ProcessRecordStatus, DynamicContext } from '@explorins/pers-shared';
2
+ import type { RedemptionCreateRequestDTO, RedemptionDTO, RedemptionRedeemDTO, RedemptionRedeemRequestResponseDTO, RedemptionTypeDTO, PaginatedResponseDTO, RedemptionRedeemIncludeRelation, ProcessRecordStatus, DynamicContext, SortOrder } from '@explorins/pers-shared';
3
3
  import type { RedemptionRedeemFilters } from '@explorins/pers-sdk/redemption';
4
4
  import type { PaginationOptions } from '@explorins/pers-sdk';
5
- export type { RedemptionRedeemFilters } from '@explorins/pers-sdk/redemption';
5
+ export type { RedemptionRedeemFilters, RedemptionFilterOptions } from '@explorins/pers-sdk/redemption';
6
+ /**
7
+ * Options for fetching redemptions with filtering and pagination
8
+ */
9
+ export interface GetRedemptionsOptions {
10
+ /** Filter by active status (Admin only - regular users always see active offers) */
11
+ active?: boolean;
12
+ /** Free text search across name, description, tags (case-insensitive) */
13
+ search?: string;
14
+ /** Page number (1-indexed) */
15
+ page?: number;
16
+ /** Results per page */
17
+ limit?: number;
18
+ /** Field to sort by */
19
+ sortBy?: 'name' | 'createdAt';
20
+ /** Sort direction */
21
+ sortOrder?: SortOrder;
22
+ }
6
23
  export declare const useRedemptions: () => {
7
- getRedemptions: (options?: {
8
- active?: boolean;
9
- }) => Promise<PaginatedResponseDTO<RedemptionDTO>>;
24
+ getRedemptions: (options?: GetRedemptionsOptions) => Promise<PaginatedResponseDTO<RedemptionDTO>>;
10
25
  getUserRedemptions: (filters?: {
11
26
  redemptionId?: string;
12
27
  status?: ProcessRecordStatus;
@@ -1 +1 @@
1
- {"version":3,"file":"useRedemptions.d.ts","sourceRoot":"","sources":["../../src/hooks/useRedemptions.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,KAAK,EACV,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,kCAAkC,EAClC,iBAAiB,EACjB,oBAAoB,EACpB,+BAA+B,EAC/B,mBAAmB,EACnB,cAAc,EACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,YAAY,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAE9E,eAAO,MAAM,cAAc;+BAY2B;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,KAAG,QAAQ,qBAAqB,aAAa,CAAC,CAAC;mCAyC3G;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,mBAAmB,CAAA;KAAE,YACvD,iBAAiB,YACjB,+BAA+B,EAAE,KAC1C,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;2BAkErC,MAAM,YACV;QAAE,OAAO,CAAC,EAAE,cAAc,CAAC;QAAC,cAAc,CAAC,EAAE,gBAAgB,CAAA;KAAE,KACxE,QAAQ,kCAAkC,CAAC;8BAmGG,QAAQ,qBAAqB,iBAAiB,CAAC,CAAC;qCA9BrF,uBAAuB,YACvB,+BAA+B,EAAE,KAC1C,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;uCAcO,0BAA0B,KAAG,QAAQ,aAAa,CAAC;qCA4BrD,MAAM,kBAAkB,0BAA0B,KAAG,QAAQ,aAAa,CAAC;2CAcrE,MAAM,KAAG,QAAQ,aAAa,CAAC;;;;CA4BhG,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
1
+ {"version":3,"file":"useRedemptions.d.ts","sourceRoot":"","sources":["../../src/hooks/useRedemptions.ts"],"names":[],"mappings":"AAEA,OAAO,EAA0C,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAClG,OAAO,KAAK,EACV,0BAA0B,EAC1B,aAAa,EACb,mBAAmB,EACnB,kCAAkC,EAClC,iBAAiB,EACjB,oBAAoB,EACpB,+BAA+B,EAC/B,mBAAmB,EACnB,cAAc,EACd,SAAS,EACV,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,uBAAuB,EAA2B,MAAM,gCAAgC,CAAC;AACvG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAG7D,YAAY,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEvG;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,oFAAoF;IACpF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8BAA8B;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uBAAuB;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,WAAW,CAAC;IAC9B,qBAAqB;IACrB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED,eAAO,MAAM,cAAc;+BAyC2B,qBAAqB,KAAG,QAAQ,qBAAqB,aAAa,CAAC,CAAC;mCAyC5G;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,mBAAmB,CAAA;KAAE,YACvD,iBAAiB,YACjB,+BAA+B,EAAE,KAC1C,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;2BAkErC,MAAM,YACV;QAAE,OAAO,CAAC,EAAE,cAAc,CAAC;QAAC,cAAc,CAAC,EAAE,gBAAgB,CAAA;KAAE,KACxE,QAAQ,kCAAkC,CAAC;8BAmGG,QAAQ,qBAAqB,iBAAiB,CAAC,CAAC;qCA9BrF,uBAAuB,YACvB,+BAA+B,EAAE,KAC1C,QAAQ,qBAAqB,mBAAmB,CAAC,CAAC;uCAcO,0BAA0B,KAAG,QAAQ,aAAa,CAAC;qCA4BrD,MAAM,kBAAkB,0BAA0B,KAAG,QAAQ,aAAa,CAAC;2CAcrE,MAAM,KAAG,QAAQ,aAAa,CAAC;;;;CA4BhG,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC"}
@@ -11,6 +11,35 @@ export const useRedemptions = () => {
11
11
  * **Administrators:** Can see all redemptions and filter by active/inactive status
12
12
  *
13
13
  * The backend enforces permission-based filtering automatically.
14
+ *
15
+ * @param options - Filter and pagination options
16
+ * @param options.active - Filter by active status (Admin only)
17
+ * @param options.search - Free text search across name, description, tags
18
+ * @param options.page - Page number (1-indexed)
19
+ * @param options.limit - Results per page
20
+ * @param options.sortBy - Field to sort by ('name' | 'createdAt')
21
+ * @param options.sortOrder - Sort direction ('ASC' | 'DESC')
22
+ *
23
+ * @example Basic usage
24
+ * ```typescript
25
+ * const { data: offers } = await getRedemptions();
26
+ * ```
27
+ *
28
+ * @example Search redemptions
29
+ * ```typescript
30
+ * const { data: coffeeOffers } = await getRedemptions({ search: 'coffee' });
31
+ * ```
32
+ *
33
+ * @example With pagination and sorting
34
+ * ```typescript
35
+ * const { data, pagination } = await getRedemptions({
36
+ * search: 'discount',
37
+ * page: 1,
38
+ * limit: 10,
39
+ * sortBy: 'name',
40
+ * sortOrder: 'ASC'
41
+ * });
42
+ * ```
14
43
  */
15
44
  const getRedemptions = useCallback(async (options) => {
16
45
  if (!isInitialized || !sdk) {
@@ -1 +1 @@
1
- {"version":3,"file":"useTransactionSigner.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactionSigner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,aAAa,EAAkB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI3G,KAAK,gBAAgB,GAAG,OAAO,qCAAqC,EAAE,gBAAgB,CAAC;AACvF,KAAK,iBAAiB,GAAG,OAAO,qCAAqC,EAAE,iBAAiB,CAAC;AACzF,KAAK,wBAAwB,GAAG,OAAO,qCAAqC,EAAE,wBAAwB,CAAC;AAGvG,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAczG;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/G,mBAAmB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC3G,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgLG;AACH,eAAO,MAAM,oBAAoB,QAAO,qBA2TvC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,CAAC"}
1
+ {"version":3,"file":"useTransactionSigner.d.ts","sourceRoot":"","sources":["../../src/hooks/useTransactionSigner.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,aAAa,EAAkB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAI3G,KAAK,gBAAgB,GAAG,OAAO,qCAAqC,EAAE,gBAAgB,CAAC;AACvF,KAAK,iBAAiB,GAAG,OAAO,qCAAqC,EAAE,iBAAiB,CAAC;AACzF,KAAK,wBAAwB,GAAG,OAAO,qCAAqC,EAAE,wBAAwB,CAAC;AAGvG,OAAO,EAAE,aAAa,EAAE,CAAC;AACzB,YAAY,EAAE,gBAAgB,EAAE,CAAC;AAEjC;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,gBAAgB,KAAK,IAAI,CAAC;AA4CzG;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,qBAAqB;IACpC,+BAA+B,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/G,mBAAmB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,CAAC,EAAE,gBAAgB,KAAK,OAAO,CAAC,wBAAwB,CAAC,CAAC;IAC3G,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgLG;AACH,eAAO,MAAM,oBAAoB,QAAO,qBA4TvC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,CAAC"}
@@ -3,15 +3,41 @@ import { useCallback, useState, useRef, useEffect } from 'react';
3
3
  import { SigningStatus } from '@explorins/pers-signer';
4
4
  // Re-export signing status types from signer SDK for convenience
5
5
  export { SigningStatus };
6
- // Dynamic import the signer SDK to avoid build issues with static dependencies
7
- let createPersSignerSDK = null;
8
- try {
9
- const signerModule = require('@explorins/pers-signer/react-native');
10
- createPersSignerSDK = signerModule.createPersSignerSDK;
11
- }
12
- catch (error) {
13
- console.warn('[useTransactionSigner] PERS Signer SDK not available:', error.message);
14
- console.warn('[useTransactionSigner] Real blockchain signing will not be available');
6
+ // Lazy-loaded signer SDK factory - initialized on first use to avoid native module timing issues
7
+ let _createPersSignerSDK = null;
8
+ let _signerInitAttempted = false;
9
+ /**
10
+ * Lazily load the PERS Signer SDK.
11
+ *
12
+ * Supports customer pre-initialization via global.__PersSigner for environments
13
+ * where native module timing is unpredictable (e.g., certain React Native setups).
14
+ *
15
+ * @returns The createPersSignerSDK function or null if unavailable
16
+ */
17
+ function getSignerSDKFactory() {
18
+ if (_signerInitAttempted) {
19
+ // Already tried - return cached result (could be null if failed)
20
+ return _createPersSignerSDK;
21
+ }
22
+ _signerInitAttempted = true;
23
+ // Check for customer pre-initialized global (for native module timing issues)
24
+ if (typeof global !== 'undefined' && global.__PersSigner?.createPersSignerSDK) {
25
+ _createPersSignerSDK = global.__PersSigner.createPersSignerSDK;
26
+ return _createPersSignerSDK;
27
+ }
28
+ // Standard lazy load
29
+ try {
30
+ const signerModule = require('@explorins/pers-signer/react-native');
31
+ _createPersSignerSDK = signerModule.createPersSignerSDK;
32
+ return _createPersSignerSDK;
33
+ }
34
+ catch (error) {
35
+ console.warn('[useTransactionSigner] PERS Signer SDK not available:', error.message);
36
+ console.warn('[useTransactionSigner] Real blockchain signing will not be available');
37
+ console.warn('[useTransactionSigner] Tip: If timing issues, pre-initialize in index.js: global.__PersSigner = require("@explorins/pers-signer/react-native")');
38
+ _createPersSignerSDK = null; // Mark as unavailable
39
+ return null;
40
+ }
15
41
  }
16
42
  // Constants - TODO: Move to environment config later
17
43
  const DEFAULT_ETHERS_PROVIDER = "https://sepolia.infura.io/v3/2781b4b5242343d5b0954c98f287b29e";
@@ -201,6 +227,7 @@ export const useTransactionSigner = () => {
201
227
  // Auto-initialize signer SDK when PERS SDK is ready
202
228
  useEffect(() => {
203
229
  const initializeSignerSDK = async () => {
230
+ const createPersSignerSDK = getSignerSDKFactory();
204
231
  if (!createPersSignerSDK) {
205
232
  console.warn('[useTransactionSigner] Signer SDK not available');
206
233
  return;
@@ -315,7 +342,7 @@ export const useTransactionSigner = () => {
315
342
  if (!isSignerInitialized || !signerSDKRef.current) {
316
343
  throw new Error('Transaction signer not initialized');
317
344
  }
318
- if (!createPersSignerSDK) {
345
+ if (!getSignerSDKFactory()) {
319
346
  throw new Error('PERS Signer SDK not available. Blockchain signing is not supported.');
320
347
  }
321
348
  // Create status callback wrapper that updates both hook state and calls user callback
@@ -459,7 +486,7 @@ export const useTransactionSigner = () => {
459
486
  * );
460
487
  * ```
461
488
  */
462
- isSignerAvailable: isSignerInitialized && !!createPersSignerSDK,
489
+ isSignerAvailable: isSignerInitialized && !!getSignerSDKFactory(),
463
490
  /**
464
491
  * Current signing status for UI feedback
465
492
  *