@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 +108 -14
- package/dist/hooks/useCampaigns.d.ts +2 -0
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.d.ts +20 -5
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +29 -0
- package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
- package/dist/hooks/useTransactionSigner.js +38 -11
- package/dist/index.js +216 -76
- package/dist/index.js.map +1 -1
- package/dist/providers/rn-dpop-provider.d.ts.map +1 -1
- package/dist/providers/rn-dpop-provider.js +48 -12
- package/package.json +2 -2
- package/src/hooks/useCampaigns.ts +2 -0
- package/src/hooks/useRedemptions.ts +52 -4
- package/src/hooks/useTransactionSigner.ts +41 -10
- package/src/providers/rn-dpop-provider.ts +57 -11
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
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,
|
|
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;
|
|
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
|
-
//
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 (!
|
|
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 && !!
|
|
489
|
+
isSignerAvailable: isSignerInitialized && !!getSignerSDKFactory(),
|
|
463
490
|
/**
|
|
464
491
|
* Current signing status for UI feedback
|
|
465
492
|
*
|