@explorins/pers-sdk-react-native 2.1.12 → 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/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.d.ts +2 -0
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +58 -1
- package/dist/hooks/useRedemptions.d.ts +28 -7
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +91 -10
- package/dist/hooks/useTokenBalances.d.ts +8 -1
- package/dist/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/hooks/useTokenBalances.js +8 -1
- package/dist/hooks/useTransactionSigner.d.ts.map +1 -1
- package/dist/hooks/useTransactionSigner.js +38 -11
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +461 -116
- 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 +3 -3
- package/src/hooks/index.ts +1 -1
- package/src/hooks/useCampaigns.ts +62 -2
- package/src/hooks/useRedemptions.ts +119 -13
- package/src/hooks/useTokenBalances.ts +8 -1
- package/src/hooks/useTransactionSigner.ts +41 -10
- package/src/index.ts +1 -1
- 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
|
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -21,7 +21,7 @@ export type { TransactionSignerHook, SubmissionResult, AuthenticatedUser, Transa
|
|
|
21
21
|
export type { AccountOwnedTokensResult, Web3Hook } from './useWeb3';
|
|
22
22
|
export type { EventsHook, PersEvent, EventHandler, EventFilter, Unsubscribe } from './useEvents';
|
|
23
23
|
export type { TokenBalanceWithToken, UseTokenBalancesOptions, UseTokenBalancesResult } from './useTokenBalances';
|
|
24
|
-
export type { CampaignClaimFilters, CampaignHook } from './useCampaigns';
|
|
24
|
+
export type { CampaignClaimFilters, CampaignHook, GetCampaignsOptions } from './useCampaigns';
|
|
25
25
|
export type { RedemptionRedeemFilters, RedemptionHook } from './useRedemptions';
|
|
26
26
|
export type { TransactionQueryOptions, TransactionHook } from './useTransactions';
|
|
27
27
|
export type { TriggerSourceQueryOptions, TriggerSourceHook } from './useTriggerSources';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EACnC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjG,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAC7E,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC7C,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EACnC,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,wBAAwB,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACpE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACjG,YAAY,EACV,qBAAqB,EACrB,uBAAuB,EACvB,sBAAsB,EACvB,MAAM,oBAAoB,CAAC;AAG5B,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG9F,YAAY,EAAE,uBAAuB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGhF,YAAY,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAGlF,YAAY,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGxF,YAAY,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC"}
|
|
@@ -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,
|
|
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"}
|
|
@@ -70,6 +70,63 @@ export const useCampaigns = () => {
|
|
|
70
70
|
throw error;
|
|
71
71
|
}
|
|
72
72
|
}, [sdk, isInitialized]);
|
|
73
|
+
/**
|
|
74
|
+
* Claim a campaign reward with optional dynamic context
|
|
75
|
+
*
|
|
76
|
+
* Triggers a campaign claim for the authenticated user. The campaign must be active
|
|
77
|
+
* and the user must meet all eligibility requirements. Supports dynamic context for
|
|
78
|
+
* personalized NFT generation when the campaign issues ERC721 tokens.
|
|
79
|
+
*
|
|
80
|
+
* @param request - Campaign claim request with optional context
|
|
81
|
+
* @param request.campaignId - ID of the campaign to claim (optional if using triggerSourceId)
|
|
82
|
+
* @param request.triggerSourceId - ID of trigger source (QR, NFC, etc.)
|
|
83
|
+
* @param request.context - Dynamic context for NFT personalization
|
|
84
|
+
* @param request.metadata - Additional metadata for the claim
|
|
85
|
+
* @param request.latitude - User's latitude for geo-validated claims
|
|
86
|
+
* @param request.longitude - User's longitude for geo-validated claims
|
|
87
|
+
* @returns Promise resolving to campaign claim result
|
|
88
|
+
*
|
|
89
|
+
* @example Basic campaign claim
|
|
90
|
+
* ```typescript
|
|
91
|
+
* const claim = await claimCampaign({
|
|
92
|
+
* triggerSourceId: 'qr-code-123',
|
|
93
|
+
* });
|
|
94
|
+
* ```
|
|
95
|
+
*
|
|
96
|
+
* @example Campaign claim with dynamic context (personalized NFT)
|
|
97
|
+
* ```typescript
|
|
98
|
+
* import { DynamicContext } from '@explorins/pers-sdk-react-native';
|
|
99
|
+
*
|
|
100
|
+
* const context: DynamicContext = {
|
|
101
|
+
* // Validity - token valid for 30 days
|
|
102
|
+
* validityDate: new Date().toISOString(),
|
|
103
|
+
* validityDuration: 30,
|
|
104
|
+
*
|
|
105
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
106
|
+
* visitorName: 'John Doe',
|
|
107
|
+
* visitLocation: 'Grand Hotel Lobby',
|
|
108
|
+
* membershipTier: 'Gold',
|
|
109
|
+
* };
|
|
110
|
+
*
|
|
111
|
+
* const claim = await claimCampaign({
|
|
112
|
+
* triggerSourceId: 'hotel-checkin-qr',
|
|
113
|
+
* context,
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @example Geo-validated claim with context
|
|
118
|
+
* ```typescript
|
|
119
|
+
* const claim = await claimCampaign({
|
|
120
|
+
* triggerSourceId: 'museum-entrance-nfc',
|
|
121
|
+
* latitude: 48.8606,
|
|
122
|
+
* longitude: 2.3376,
|
|
123
|
+
* context: {
|
|
124
|
+
* visitorType: 'Adult',
|
|
125
|
+
* ticketCategory: 'General Admission',
|
|
126
|
+
* }
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*/
|
|
73
130
|
const claimCampaign = useCallback(async (request) => {
|
|
74
131
|
if (!isInitialized || !sdk) {
|
|
75
132
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
@@ -97,7 +154,7 @@ export const useCampaigns = () => {
|
|
|
97
154
|
* // Get user's claims with campaign details
|
|
98
155
|
* const { data: claims } = await getUserClaims({ include: ['campaign', 'business'] });
|
|
99
156
|
* claims.forEach(claim => {
|
|
100
|
-
* console.log('Campaign:', claim.included?.campaign?.
|
|
157
|
+
* console.log('Campaign:', claim.included?.campaign?.name);
|
|
101
158
|
* });
|
|
102
159
|
*
|
|
103
160
|
* // With pagination
|
|
@@ -1,14 +1,35 @@
|
|
|
1
1
|
import { OnStatusUpdateFn } from './useTransactionSigner';
|
|
2
|
-
import type { RedemptionCreateRequestDTO, RedemptionDTO, RedemptionRedeemDTO, RedemptionRedeemRequestResponseDTO, RedemptionTypeDTO, PaginatedResponseDTO, RedemptionRedeemIncludeRelation } 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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
24
|
+
getRedemptions: (options?: GetRedemptionsOptions) => Promise<PaginatedResponseDTO<RedemptionDTO>>;
|
|
25
|
+
getUserRedemptions: (filters?: {
|
|
26
|
+
redemptionId?: string;
|
|
27
|
+
status?: ProcessRecordStatus;
|
|
28
|
+
}, options?: PaginationOptions, include?: RedemptionRedeemIncludeRelation[]) => Promise<PaginatedResponseDTO<RedemptionRedeemDTO>>;
|
|
29
|
+
redeem: (redemptionId: string, options?: {
|
|
30
|
+
context?: DynamicContext;
|
|
31
|
+
onStatusUpdate?: OnStatusUpdateFn;
|
|
32
|
+
}) => Promise<RedemptionRedeemRequestResponseDTO>;
|
|
12
33
|
getRedemptionTypes: () => Promise<PaginatedResponseDTO<RedemptionTypeDTO>>;
|
|
13
34
|
getRedemptionRedeems: (filters?: RedemptionRedeemFilters, include?: RedemptionRedeemIncludeRelation[]) => Promise<PaginatedResponseDTO<RedemptionRedeemDTO>>;
|
|
14
35
|
createRedemption: (redemptionData: RedemptionCreateRequestDTO) => Promise<RedemptionDTO>;
|
|
@@ -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,
|
|
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) {
|
|
@@ -26,27 +55,32 @@ export const useRedemptions = () => {
|
|
|
26
55
|
}
|
|
27
56
|
}, [sdk, isInitialized]);
|
|
28
57
|
/**
|
|
29
|
-
* Get user's redemption history with optional pagination and include relations
|
|
58
|
+
* Get user's redemption history with optional filters, pagination and include relations
|
|
30
59
|
*
|
|
60
|
+
* @param filters - Optional filters (redemptionId, status)
|
|
31
61
|
* @param options - Pagination options (page, limit, sortBy, sortOrder)
|
|
32
|
-
* @param include - Relations to include: 'redemption', 'user', 'business'
|
|
62
|
+
* @param include - Relations to include: 'redemption', 'user', 'business', 'transactions'
|
|
33
63
|
* @returns Promise resolving to paginated redemption history
|
|
34
64
|
*
|
|
35
65
|
* @example
|
|
36
66
|
* ```typescript
|
|
37
67
|
* // Get first page of user redemptions
|
|
38
|
-
* const { data: redeems, pagination } = await getUserRedemptions({ page: 1, limit: 10 });
|
|
68
|
+
* const { data: redeems, pagination } = await getUserRedemptions({}, { page: 1, limit: 10 });
|
|
39
69
|
* console.log(`Page ${pagination.page} of ${pagination.pages}`);
|
|
40
70
|
*
|
|
71
|
+
* // Get only completed redemptions
|
|
72
|
+
* import { ProcessRecordStatus } from '@explorins/pers-shared';
|
|
73
|
+
* const { data: completed } = await getUserRedemptions({ status: ProcessRecordStatus.COMPLETED });
|
|
74
|
+
*
|
|
41
75
|
* // Get user redemptions with full redemption details
|
|
42
|
-
* const { data: redeems } = await getUserRedemptions({}, ['redemption', 'business']);
|
|
76
|
+
* const { data: redeems } = await getUserRedemptions({}, {}, ['redemption', 'business']);
|
|
43
77
|
* redeems.forEach(redeem => {
|
|
44
|
-
* console.log('Redemption:', redeem.included?.redemption?.
|
|
78
|
+
* console.log('Redemption:', redeem.included?.redemption?.name);
|
|
45
79
|
* console.log('Business:', redeem.included?.business?.displayName);
|
|
46
80
|
* });
|
|
47
81
|
* ```
|
|
48
82
|
*/
|
|
49
|
-
const getUserRedemptions = useCallback(async (options, include) => {
|
|
83
|
+
const getUserRedemptions = useCallback(async (filters, options, include) => {
|
|
50
84
|
if (!isInitialized || !sdk) {
|
|
51
85
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
52
86
|
}
|
|
@@ -55,7 +89,7 @@ export const useRedemptions = () => {
|
|
|
55
89
|
return { data: [], pagination: { page: 1, limit: 0, total: 0, pages: 0, hasNext: false, hasPrev: false } };
|
|
56
90
|
}
|
|
57
91
|
try {
|
|
58
|
-
const result = await sdk.redemptions.getUserRedemptions(options, include);
|
|
92
|
+
const result = await sdk.redemptions.getUserRedemptions(filters, options, include);
|
|
59
93
|
return result;
|
|
60
94
|
}
|
|
61
95
|
catch (error) {
|
|
@@ -63,7 +97,54 @@ export const useRedemptions = () => {
|
|
|
63
97
|
throw error;
|
|
64
98
|
}
|
|
65
99
|
}, [sdk, isInitialized, isAuthenticated]);
|
|
66
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Redeem a redemption offer with optional dynamic context
|
|
102
|
+
*
|
|
103
|
+
* Supports dynamic context for personalized NFT generation when the redemption
|
|
104
|
+
* issues ERC721 tokens. Context can include validity dates, AI prompt placeholders,
|
|
105
|
+
* and custom metadata.
|
|
106
|
+
*
|
|
107
|
+
* @param redemptionId - ID of the redemption to redeem
|
|
108
|
+
* @param options - Optional settings
|
|
109
|
+
* @param options.context - Dynamic context for NFT personalization (validity dates, AI prompts)
|
|
110
|
+
* @param options.onStatusUpdate - Callback for transaction signing status updates
|
|
111
|
+
* @returns Promise resolving to redemption result
|
|
112
|
+
*
|
|
113
|
+
* @example Basic redemption
|
|
114
|
+
* ```typescript
|
|
115
|
+
* const result = await redeem('redemption-123');
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @example Redemption with dynamic context (personalized NFT)
|
|
119
|
+
* ```typescript
|
|
120
|
+
* const result = await redeem('event-ticket-123', {
|
|
121
|
+
* context: {
|
|
122
|
+
* // Validity - token valid for event duration
|
|
123
|
+
* validityDate: new Date().toISOString(),
|
|
124
|
+
* validityDuration: 8, // 8 hours
|
|
125
|
+
*
|
|
126
|
+
* // AI prompt context - available as {{context.xxx}} in prompts
|
|
127
|
+
* attendeeName: 'John Doe',
|
|
128
|
+
* ticketTier: 'VIP',
|
|
129
|
+
* seatSection: 'A12',
|
|
130
|
+
* }
|
|
131
|
+
* });
|
|
132
|
+
* ```
|
|
133
|
+
*
|
|
134
|
+
* @example Hotel stay NFT with check-in/check-out dates
|
|
135
|
+
* ```typescript
|
|
136
|
+
* const result = await redeem('hotel-nft-456', {
|
|
137
|
+
* context: {
|
|
138
|
+
* validityDate: '2026-04-15T14:00:00Z', // Check-in
|
|
139
|
+
* validityEndDate: '2026-04-20T11:00:00Z', // Check-out
|
|
140
|
+
* guestName: 'Jane Smith',
|
|
141
|
+
* roomNumber: '305',
|
|
142
|
+
* roomType: 'Suite',
|
|
143
|
+
* }
|
|
144
|
+
* });
|
|
145
|
+
* ```
|
|
146
|
+
*/
|
|
147
|
+
const redeem = useCallback(async (redemptionId, options) => {
|
|
67
148
|
if (!isInitialized || !sdk) {
|
|
68
149
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
69
150
|
}
|
|
@@ -71,11 +152,11 @@ export const useRedemptions = () => {
|
|
|
71
152
|
throw new Error('SDK not authenticated. redeem requires authentication.');
|
|
72
153
|
}
|
|
73
154
|
try {
|
|
74
|
-
const result = await sdk.redemptions.redeem(redemptionId);
|
|
155
|
+
const result = await sdk.redemptions.redeem(redemptionId, options?.context);
|
|
75
156
|
const txToken = result.senderTransaction?.actionable?.authToken;
|
|
76
157
|
if (txToken && isSignerAvailable) {
|
|
77
158
|
try {
|
|
78
|
-
const signingResult = await signAndSubmitTransactionWithJWT(txToken, onStatusUpdate);
|
|
159
|
+
const signingResult = await signAndSubmitTransactionWithJWT(txToken, options?.onStatusUpdate);
|
|
79
160
|
if (signingResult.success) {
|
|
80
161
|
// Return enhanced result with signing information
|
|
81
162
|
return {
|
|
@@ -88,10 +88,17 @@ export interface UseTokenBalancesResult {
|
|
|
88
88
|
* **Basic Usage:**
|
|
89
89
|
* ```typescript
|
|
90
90
|
* import { useTokenBalances, useTokens, usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
91
|
+
* import { useState, useEffect } from 'react';
|
|
91
92
|
*
|
|
92
93
|
* function TokenBalancesScreen() {
|
|
93
94
|
* const { user } = usePersSDK();
|
|
94
|
-
* const {
|
|
95
|
+
* const { getTokens } = useTokens();
|
|
96
|
+
* const [availableTokens, setAvailableTokens] = useState([]);
|
|
97
|
+
*
|
|
98
|
+
* // Load tokens on mount
|
|
99
|
+
* useEffect(() => {
|
|
100
|
+
* getTokens().then(result => setAvailableTokens(result.data));
|
|
101
|
+
* }, []);
|
|
95
102
|
*
|
|
96
103
|
* // App explicitly selects which wallet to use
|
|
97
104
|
* const walletAddress = user?.wallets?.[0]?.address;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useTokenBalances.d.ts","sourceRoot":"","sources":["../../src/hooks/useTokenBalances.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,0BAA0B,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,8DAA8D;IAC9D,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0DAA0D;IAC1D,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uCAAuC;IACvC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,sFAAsF;IACtF,WAAW,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED
|
|
1
|
+
{"version":3,"file":"useTokenBalances.d.ts","sourceRoot":"","sources":["../../src/hooks/useTokenBalances.ts"],"names":[],"mappings":"AAGA,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,0BAA0B,CAAC;AAElF;;;;;;GAMG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,YAAY,EAAE,YAAY,CAAC;IAC3B,8DAA8D;IAC9D,KAAK,EAAE,QAAQ,CAAC;IAChB,8EAA8E;IAC9E,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,yEAAyE;IACzE,eAAe,CAAC,EAAE,QAAQ,EAAE,CAAC;IAC7B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,0DAA0D;IAC1D,aAAa,EAAE,qBAAqB,EAAE,CAAC;IACvC,6CAA6C;IAC7C,SAAS,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,uCAAuC;IACvC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,sFAAsF;IACtF,WAAW,EAAE,OAAO,CAAC;IACrB,0CAA0C;IAC1C,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8FG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,sBAAsB,CAqLzF"}
|
|
@@ -25,10 +25,17 @@ import { NativeTokenTypes } from '@explorins/pers-shared';
|
|
|
25
25
|
* **Basic Usage:**
|
|
26
26
|
* ```typescript
|
|
27
27
|
* import { useTokenBalances, useTokens, usePersSDK } from '@explorins/pers-sdk-react-native';
|
|
28
|
+
* import { useState, useEffect } from 'react';
|
|
28
29
|
*
|
|
29
30
|
* function TokenBalancesScreen() {
|
|
30
31
|
* const { user } = usePersSDK();
|
|
31
|
-
* const {
|
|
32
|
+
* const { getTokens } = useTokens();
|
|
33
|
+
* const [availableTokens, setAvailableTokens] = useState([]);
|
|
34
|
+
*
|
|
35
|
+
* // Load tokens on mount
|
|
36
|
+
* useEffect(() => {
|
|
37
|
+
* getTokens().then(result => setAvailableTokens(result.data));
|
|
38
|
+
* }, []);
|
|
32
39
|
*
|
|
33
40
|
* // App explicitly selects which wallet to use
|
|
34
41
|
* const walletAddress = user?.wallets?.[0]?.address;
|
|
@@ -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
|
*
|
package/dist/index.d.ts
CHANGED
|
@@ -210,7 +210,7 @@ export { useAuth, useTokens, useTokenBalances, useTransactions, useTransactionSi
|
|
|
210
210
|
export type { TransactionSignerHook, OnStatusUpdateFn, StatusUpdateData, SigningStatusType, TransactionSigningResult, SubmissionResult, AuthenticatedUser } from './hooks';
|
|
211
211
|
export type { EventsHook, PersEvent, EventHandler, EventFilter, Unsubscribe } from './hooks';
|
|
212
212
|
export type { TokenBalanceWithToken, UseTokenBalancesOptions, UseTokenBalancesResult } from './hooks';
|
|
213
|
-
export type { CampaignClaimFilters, CampaignHook } from './hooks';
|
|
213
|
+
export type { CampaignClaimFilters, CampaignHook, GetCampaignsOptions } from './hooks';
|
|
214
214
|
export type { RedemptionRedeemFilters, RedemptionHook } from './hooks';
|
|
215
215
|
export type { TransactionQueryOptions, TransactionHook } from './hooks';
|
|
216
216
|
export type { TriggerSourceQueryOptions, TriggerSourceHook } from './hooks';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AAGH,OAAO,aAAa,CAAC;AAMrB;;;;;;;;GAQG;AACH,OAAO,EACL,6BAA6B,EAC7B,KAAK,qBAAqB,EAC3B,MAAM,wCAAwC,CAAC;AAMhD;;;;;;;;;;GAUG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAEvE;;;;;;;;GAQG;AACH,OAAO,EACL,wBAAwB,GACzB,MAAM,uCAAuC,CAAC;AAM/C;;;GAGG;AACH,OAAO,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAMvE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EACL,eAAe,EACf,UAAU,EACV,KAAK,UAAU,EACf,KAAK,cAAc,EACpB,MAAM,6BAA6B,CAAC;AAMrC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0FG;AACH,OAAO,EACL,OAAO,EACP,SAAS,EACT,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,YAAY,EACZ,cAAc,EACd,OAAO,EACP,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,YAAY,EACZ,YAAY,EACZ,SAAS,EACT,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EACV,qBAAqB,EACrB,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,wBAAwB,EACxB,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAGjB,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAG7F,YAAY,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAGtG,YAAY,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|