@explorins/pers-sdk-react-native 2.1.5 → 2.1.6
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/dist/hooks/useEvents.d.ts +17 -5
- package/dist/hooks/useEvents.d.ts.map +1 -1
- package/dist/hooks/useEvents.js +17 -5
- package/dist/hooks/useTokenBalances.d.ts +24 -0
- package/dist/hooks/useTokenBalances.d.ts.map +1 -1
- package/dist/hooks/useTokenBalances.js +42 -2
- package/dist/hooks/useUsers.d.ts +5 -4
- package/dist/hooks/useUsers.d.ts.map +1 -1
- package/dist/hooks/useUsers.js +47 -8
- package/dist/hooks/useWeb3.d.ts +6 -5
- package/dist/hooks/useWeb3.d.ts.map +1 -1
- package/dist/hooks/useWeb3.js +23 -10
- package/dist/index.js +3041 -500
- package/dist/index.js.map +1 -1
- package/dist/providers/PersSDKProvider.d.ts +38 -0
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +29 -1
- package/package.json +3 -2
- package/src/hooks/useEvents.ts +17 -5
- package/src/hooks/useTokenBalances.ts +60 -2
- package/src/hooks/useUsers.ts +51 -9
- package/src/hooks/useWeb3.ts +28 -13
- package/src/providers/PersSDKProvider.tsx +38 -1
|
@@ -2,6 +2,15 @@ import React, { ReactNode } from 'react';
|
|
|
2
2
|
import { PersSDK, PersConfig, DefaultAuthProvider } from '@explorins/pers-sdk/core';
|
|
3
3
|
import { UserDTO, AdminDTO } from '@explorins/pers-shared';
|
|
4
4
|
export type { PersConfig } from '@explorins/pers-sdk/core';
|
|
5
|
+
/**
|
|
6
|
+
* Context interface for PERS SDK React Native integration
|
|
7
|
+
*
|
|
8
|
+
* @property sdk - Main SDK instance (null until initialized)
|
|
9
|
+
* @property authProvider - Platform-specific auth provider
|
|
10
|
+
* @property isInitialized - Whether SDK has been initialized
|
|
11
|
+
* @property isAuthenticated - Whether user is currently authenticated
|
|
12
|
+
* @property user - Current user data (null if not authenticated)
|
|
13
|
+
*/
|
|
5
14
|
export interface PersSDKContext {
|
|
6
15
|
sdk: PersSDK | null;
|
|
7
16
|
authProvider: DefaultAuthProvider | null;
|
|
@@ -13,6 +22,35 @@ export interface PersSDKContext {
|
|
|
13
22
|
refreshUserData: () => Promise<void>;
|
|
14
23
|
restoreSession: () => Promise<UserDTO | null>;
|
|
15
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* PERS SDK Provider for React Native
|
|
27
|
+
*
|
|
28
|
+
* Wraps your app to provide SDK context to all child components.
|
|
29
|
+
* Handles platform-specific initialization (DPoP, storage, etc.).
|
|
30
|
+
*
|
|
31
|
+
* @param config - SDK configuration (see PersConfig)
|
|
32
|
+
* @param config.apiProjectKey - Your PERS project key (required)
|
|
33
|
+
* @param config.environment - 'staging' | 'production' (default: 'staging')
|
|
34
|
+
* @param config.captureWalletEvents - Enable real-time blockchain events (default: true)
|
|
35
|
+
* @param config.dpop - DPoP configuration for enhanced security
|
|
36
|
+
*
|
|
37
|
+
* @example Basic usage
|
|
38
|
+
* ```tsx
|
|
39
|
+
* <PersSDKProvider config={{ apiProjectKey: 'my-project' }}>
|
|
40
|
+
* <App />
|
|
41
|
+
* </PersSDKProvider>
|
|
42
|
+
* ```
|
|
43
|
+
*
|
|
44
|
+
* @example Disable wallet events
|
|
45
|
+
* ```tsx
|
|
46
|
+
* <PersSDKProvider config={{
|
|
47
|
+
* apiProjectKey: 'my-project',
|
|
48
|
+
* captureWalletEvents: false // Disable auto-connect to blockchain events
|
|
49
|
+
* }}>
|
|
50
|
+
* <App />
|
|
51
|
+
* </PersSDKProvider>
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
16
54
|
export declare const PersSDKProvider: React.FC<{
|
|
17
55
|
children: ReactNode;
|
|
18
56
|
config?: PersConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersSDKProvider.d.ts","sourceRoot":"","sources":["../../src/providers/PersSDKProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuC,SAAS,EAA2C,MAAM,OAAO,CAAC;AAEvH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAIpF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAkB3D,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAGpB,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAGzC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,sBAAsB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5F,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC/C;
|
|
1
|
+
{"version":3,"file":"PersSDKProvider.d.ts","sourceRoot":"","sources":["../../src/providers/PersSDKProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAuC,SAAS,EAA2C,MAAM,OAAO,CAAC;AAEvH,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAIpF,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAkB3D,YAAY,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAGpB,YAAY,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAGzC,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,EAAE,OAAO,CAAC;IACzB,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;IAGhC,UAAU,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,sBAAsB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,IAAI,EAAE,eAAe,EAAE,OAAO,KAAK,IAAI,CAAC;IAC5F,eAAe,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,cAAc,EAAE,MAAM,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;CAC/C;AAKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC;IACrC,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,CAAC;CACrB,CAwOA,CAAC;AAGF,eAAO,MAAM,UAAU,QAAO,cAQ7B,CAAC"}
|
|
@@ -7,7 +7,35 @@ import { createReactNativeAuthProvider } from './react-native-auth-provider';
|
|
|
7
7
|
import { ReactNativeDPoPProvider } from './rn-dpop-provider';
|
|
8
8
|
// Create the context
|
|
9
9
|
const SDKContext = createContext(null);
|
|
10
|
-
|
|
10
|
+
/**
|
|
11
|
+
* PERS SDK Provider for React Native
|
|
12
|
+
*
|
|
13
|
+
* Wraps your app to provide SDK context to all child components.
|
|
14
|
+
* Handles platform-specific initialization (DPoP, storage, etc.).
|
|
15
|
+
*
|
|
16
|
+
* @param config - SDK configuration (see PersConfig)
|
|
17
|
+
* @param config.apiProjectKey - Your PERS project key (required)
|
|
18
|
+
* @param config.environment - 'staging' | 'production' (default: 'staging')
|
|
19
|
+
* @param config.captureWalletEvents - Enable real-time blockchain events (default: true)
|
|
20
|
+
* @param config.dpop - DPoP configuration for enhanced security
|
|
21
|
+
*
|
|
22
|
+
* @example Basic usage
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <PersSDKProvider config={{ apiProjectKey: 'my-project' }}>
|
|
25
|
+
* <App />
|
|
26
|
+
* </PersSDKProvider>
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example Disable wallet events
|
|
30
|
+
* ```tsx
|
|
31
|
+
* <PersSDKProvider config={{
|
|
32
|
+
* apiProjectKey: 'my-project',
|
|
33
|
+
* captureWalletEvents: false // Disable auto-connect to blockchain events
|
|
34
|
+
* }}>
|
|
35
|
+
* <App />
|
|
36
|
+
* </PersSDKProvider>
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
11
39
|
export const PersSDKProvider = ({ children, config }) => {
|
|
12
40
|
const initializingRef = useRef(false);
|
|
13
41
|
// State refs for stable functions to read current values
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@explorins/pers-sdk-react-native",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.6",
|
|
4
4
|
"description": "React Native SDK for PERS Platform - Tourism Loyalty System with Blockchain Transaction Signing and WebAuthn Authentication",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"author": "eXplorins",
|
|
38
38
|
"license": "MIT",
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@explorins/pers-sdk": "^2.1.
|
|
40
|
+
"@explorins/pers-sdk": "^2.1.14",
|
|
41
41
|
"@explorins/pers-signer": "^1.0.33",
|
|
42
42
|
"buffer": "^6.0.3",
|
|
43
43
|
"ethers": "^6.15.0",
|
|
@@ -155,6 +155,7 @@
|
|
|
155
155
|
"@ethersproject/scrypt": false
|
|
156
156
|
},
|
|
157
157
|
"devDependencies": {
|
|
158
|
+
"@explorins/pers-shared": "^2.1.117",
|
|
158
159
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
159
160
|
"@rollup/plugin-json": "^6.1.0",
|
|
160
161
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
package/src/hooks/useEvents.ts
CHANGED
|
@@ -35,23 +35,35 @@ export interface EventsHook {
|
|
|
35
35
|
* React Native hook for PERS SDK event system
|
|
36
36
|
*
|
|
37
37
|
* This hook provides access to the platform-agnostic event system for subscribing to
|
|
38
|
-
* transaction, authentication, campaign, and system events. All events
|
|
39
|
-
* `userMessage` field ready for display to end users.
|
|
38
|
+
* transaction, authentication, campaign, blockchain, and system events. All events
|
|
39
|
+
* include a `userMessage` field ready for display to end users.
|
|
40
40
|
*
|
|
41
41
|
* **Event Domains:**
|
|
42
42
|
* - `auth` - Authentication events (login, logout, token refresh)
|
|
43
43
|
* - `user` - User profile events (update, create)
|
|
44
|
-
* - `transaction` - Transaction events (created,
|
|
44
|
+
* - `transaction` - Transaction events (created, submitted, confirmed)
|
|
45
45
|
* - `campaign` - Campaign events (claimed, activated)
|
|
46
46
|
* - `redemption` - Redemption events (redeemed, expired)
|
|
47
47
|
* - `business` - Business events (created, updated, membership)
|
|
48
|
+
* - `wallet` - Real-time blockchain events (Transfer, Approval, etc.) - Auto-enabled on auth
|
|
48
49
|
* - `api` - API error events (network, validation, server errors)
|
|
49
50
|
*
|
|
51
|
+
* **Blockchain Events (Wallet Domain):**
|
|
52
|
+
* When `sdk.connectWalletEvents()` is called (or auto-enabled via `captureWalletEvents: true`),
|
|
53
|
+
* real-time blockchain events are automatically routed through the same event system:
|
|
54
|
+
* ```typescript
|
|
55
|
+
* const { subscribe } = useEvents();
|
|
56
|
+
*
|
|
57
|
+
* subscribe((event) => {
|
|
58
|
+
* if (event.domain === 'wallet') {
|
|
59
|
+
* console.log('Blockchain event:', event.type); // wallet_transfer, wallet_approval, etc.
|
|
60
|
+
* }
|
|
61
|
+
* });
|
|
62
|
+
* ```
|
|
63
|
+
*
|
|
50
64
|
* **Notification Levels:**
|
|
51
65
|
* - `success` - Operation completed successfully
|
|
52
66
|
* - `error` - Operation failed
|
|
53
|
-
* - `warning` - Operation completed with warnings
|
|
54
|
-
* - `info` - Informational event
|
|
55
67
|
*
|
|
56
68
|
* **Cleanup:**
|
|
57
69
|
* All subscriptions created through this hook are automatically cleaned up when
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
1
|
+
import { useCallback, useEffect, useState, useRef } from 'react';
|
|
2
2
|
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
3
|
import { useWeb3 } from './useWeb3';
|
|
4
4
|
import { NativeTokenTypes, type TokenDTO } from '@explorins/pers-shared';
|
|
@@ -36,6 +36,18 @@ export interface UseTokenBalancesOptions {
|
|
|
36
36
|
autoLoad?: boolean;
|
|
37
37
|
/** Optional refresh interval in milliseconds (0 = disabled) */
|
|
38
38
|
refreshInterval?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Auto-refresh balances when wallet events are received (Transfer, Approval, etc.)
|
|
41
|
+
* Requires `captureWalletEvents: true` in SDK config (default)
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
refreshOnWalletEvents?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Debounce time for wallet event-triggered refreshes (milliseconds)
|
|
47
|
+
* Prevents rapid refresh calls during batch transfers
|
|
48
|
+
* @default 1000
|
|
49
|
+
*/
|
|
50
|
+
walletEventDebounceMs?: number;
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
/**
|
|
@@ -126,6 +138,18 @@ export interface UseTokenBalancesResult {
|
|
|
126
138
|
* ```
|
|
127
139
|
*
|
|
128
140
|
* @example
|
|
141
|
+
* **With Wallet Events (Real-time):**
|
|
142
|
+
* ```typescript
|
|
143
|
+
* // Auto-refresh on Transfer, Approval, and other blockchain events
|
|
144
|
+
* const { tokenBalances } = useTokenBalances({
|
|
145
|
+
* accountAddress: walletAddress!,
|
|
146
|
+
* availableTokens,
|
|
147
|
+
* refreshOnWalletEvents: true, // Enable real-time refresh (default: true)
|
|
148
|
+
* walletEventDebounceMs: 1000 // Debounce rapid events (default: 1000ms)
|
|
149
|
+
* });
|
|
150
|
+
* ```
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
129
153
|
* **Multi-Wallet Support:**
|
|
130
154
|
* ```typescript
|
|
131
155
|
* function MultiWalletBalances() {
|
|
@@ -148,7 +172,9 @@ export function useTokenBalances(options: UseTokenBalancesOptions): UseTokenBala
|
|
|
148
172
|
accountAddress,
|
|
149
173
|
availableTokens = [],
|
|
150
174
|
autoLoad = true,
|
|
151
|
-
refreshInterval = 0
|
|
175
|
+
refreshInterval = 0,
|
|
176
|
+
refreshOnWalletEvents = true,
|
|
177
|
+
walletEventDebounceMs = 1000
|
|
152
178
|
} = options;
|
|
153
179
|
|
|
154
180
|
const { isAuthenticated, sdk } = usePersSDK();
|
|
@@ -157,6 +183,9 @@ export function useTokenBalances(options: UseTokenBalancesOptions): UseTokenBala
|
|
|
157
183
|
const [tokenBalances, setTokenBalances] = useState<TokenBalanceWithToken[]>([]);
|
|
158
184
|
const [isLoading, setIsLoading] = useState(false);
|
|
159
185
|
const [error, setError] = useState<string | null>(null);
|
|
186
|
+
|
|
187
|
+
// Debounce ref for wallet events
|
|
188
|
+
const walletEventDebounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
160
189
|
|
|
161
190
|
// Check if the hook is available for use
|
|
162
191
|
const isAvailable = web3.isAvailable && isAuthenticated && !!accountAddress;
|
|
@@ -293,6 +322,35 @@ export function useTokenBalances(options: UseTokenBalancesOptions): UseTokenBala
|
|
|
293
322
|
};
|
|
294
323
|
}, [sdk, refreshInterval, isAvailable, loadBalances]);
|
|
295
324
|
|
|
325
|
+
// Wallet events refresh: listen for real-time blockchain events
|
|
326
|
+
// Refreshes on ANY wallet domain event (Transfer, TransferSingle, etc.)
|
|
327
|
+
// Debouncing prevents excessive API calls during rapid events
|
|
328
|
+
useEffect(() => {
|
|
329
|
+
if (!sdk || !refreshOnWalletEvents || !isAvailable) return;
|
|
330
|
+
|
|
331
|
+
const unsubscribe = sdk.events.subscribe((event) => {
|
|
332
|
+
if (event.domain === 'wallet') {
|
|
333
|
+
// Debounce rapid events (batch transfers, etc.)
|
|
334
|
+
if (walletEventDebounceRef.current) {
|
|
335
|
+
clearTimeout(walletEventDebounceRef.current);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
walletEventDebounceRef.current = setTimeout(() => {
|
|
339
|
+
console.log(`[useTokenBalances] Wallet event (${event.type}), refreshing balances...`);
|
|
340
|
+
loadBalances();
|
|
341
|
+
walletEventDebounceRef.current = null;
|
|
342
|
+
}, walletEventDebounceMs);
|
|
343
|
+
}
|
|
344
|
+
}, { domains: ['wallet'] });
|
|
345
|
+
|
|
346
|
+
return () => {
|
|
347
|
+
unsubscribe();
|
|
348
|
+
if (walletEventDebounceRef.current) {
|
|
349
|
+
clearTimeout(walletEventDebounceRef.current);
|
|
350
|
+
}
|
|
351
|
+
};
|
|
352
|
+
}, [sdk, refreshOnWalletEvents, walletEventDebounceMs, isAvailable, loadBalances]);
|
|
353
|
+
|
|
296
354
|
return {
|
|
297
355
|
tokenBalances,
|
|
298
356
|
isLoading,
|
package/src/hooks/useUsers.ts
CHANGED
|
@@ -1,12 +1,31 @@
|
|
|
1
1
|
import { useCallback } from 'react';
|
|
2
2
|
import { usePersSDK } from '../providers/PersSDKProvider';
|
|
3
3
|
import type { UserDTO, UserCreateRequestDTO, PaginatedResponseDTO } from '@explorins/pers-shared';
|
|
4
|
-
import type { UserPublicProfileDTO } from '@explorins/pers-sdk/user';
|
|
4
|
+
import type { UserPublicProfileDTO, UserQueryOptions } from '@explorins/pers-sdk/user';
|
|
5
|
+
|
|
6
|
+
// Re-export for consumers
|
|
7
|
+
export type { UserQueryOptions } from '@explorins/pers-sdk/user';
|
|
5
8
|
|
|
6
9
|
export const useUsers = () => {
|
|
7
10
|
const { sdk, isInitialized, isAuthenticated } = usePersSDK();
|
|
8
11
|
|
|
9
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Get the current authenticated user with optional include relations
|
|
14
|
+
*
|
|
15
|
+
* @param options - Query options including include relations
|
|
16
|
+
* @returns Current user data
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* // Basic
|
|
21
|
+
* const user = await getCurrentUser();
|
|
22
|
+
*
|
|
23
|
+
* // With wallets included
|
|
24
|
+
* const userWithWallets = await getCurrentUser({ include: ['wallets'] });
|
|
25
|
+
* console.log('Wallets:', userWithWallets.included?.wallets);
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
const getCurrentUser = useCallback(async (options?: UserQueryOptions): Promise<UserDTO> => {
|
|
10
29
|
if (!isInitialized || !sdk) {
|
|
11
30
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
12
31
|
}
|
|
@@ -15,7 +34,7 @@ export const useUsers = () => {
|
|
|
15
34
|
}
|
|
16
35
|
|
|
17
36
|
try {
|
|
18
|
-
const result = await sdk.users.getCurrentUser();
|
|
37
|
+
const result = await sdk.users.getCurrentUser(options);
|
|
19
38
|
return result;
|
|
20
39
|
} catch (error) {
|
|
21
40
|
console.error('Failed to fetch current user:', error);
|
|
@@ -40,13 +59,29 @@ export const useUsers = () => {
|
|
|
40
59
|
}
|
|
41
60
|
}, [sdk, isInitialized, isAuthenticated]);
|
|
42
61
|
|
|
43
|
-
|
|
62
|
+
/**
|
|
63
|
+
* Get user by ID with optional include relations
|
|
64
|
+
*
|
|
65
|
+
* @param userId - User identifier (id, email, externalId, etc.)
|
|
66
|
+
* @param options - Query options including include relations
|
|
67
|
+
* @returns User data
|
|
68
|
+
*
|
|
69
|
+
* @example
|
|
70
|
+
* ```typescript
|
|
71
|
+
* // Basic
|
|
72
|
+
* const user = await getUserById('user-123');
|
|
73
|
+
*
|
|
74
|
+
* // With wallets included
|
|
75
|
+
* const userWithWallets = await getUserById('user-123', { include: ['wallets'] });
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
const getUserById = useCallback(async (userId: string, options?: UserQueryOptions): Promise<UserDTO> => {
|
|
44
79
|
if (!isInitialized || !sdk) {
|
|
45
80
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
46
81
|
}
|
|
47
82
|
|
|
48
83
|
try {
|
|
49
|
-
const result = await sdk.users.getUserById(userId);
|
|
84
|
+
const result = await sdk.users.getUserById(userId, options);
|
|
50
85
|
return result;
|
|
51
86
|
} catch (error) {
|
|
52
87
|
console.error('Failed to fetch user:', error);
|
|
@@ -97,16 +132,23 @@ export const useUsers = () => {
|
|
|
97
132
|
}
|
|
98
133
|
}, [sdk, isInitialized]);
|
|
99
134
|
|
|
100
|
-
|
|
135
|
+
/**
|
|
136
|
+
* Toggle or set a user's active status (admin only)
|
|
137
|
+
*
|
|
138
|
+
* @param userId - User ID to update
|
|
139
|
+
* @param isActive - Optional explicit status. If omitted, toggles current status.
|
|
140
|
+
* @returns Updated user
|
|
141
|
+
*/
|
|
142
|
+
const setUserActiveStatus = useCallback(async (userId: string, isActive?: boolean): Promise<UserDTO> => {
|
|
101
143
|
if (!isInitialized || !sdk) {
|
|
102
144
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
103
145
|
}
|
|
104
146
|
|
|
105
147
|
try {
|
|
106
|
-
const result = await sdk.users.
|
|
148
|
+
const result = await sdk.users.setUserActiveStatus(userId, isActive);
|
|
107
149
|
return result;
|
|
108
150
|
} catch (error) {
|
|
109
|
-
console.error('Failed to
|
|
151
|
+
console.error('Failed to set user active status:', error);
|
|
110
152
|
throw error;
|
|
111
153
|
}
|
|
112
154
|
}, [sdk, isInitialized]);
|
|
@@ -118,7 +160,7 @@ export const useUsers = () => {
|
|
|
118
160
|
getAllUsersPublic,
|
|
119
161
|
getAllUsers,
|
|
120
162
|
updateUser,
|
|
121
|
-
|
|
163
|
+
setUserActiveStatus,
|
|
122
164
|
isAvailable: isInitialized && !!sdk?.users,
|
|
123
165
|
};
|
|
124
166
|
};
|
package/src/hooks/useWeb3.ts
CHANGED
|
@@ -9,8 +9,10 @@ import type {
|
|
|
9
9
|
TokenMetadata,
|
|
10
10
|
AccountOwnedTokensResult
|
|
11
11
|
} from '@explorins/pers-sdk/web3';
|
|
12
|
-
import type {
|
|
13
|
-
|
|
12
|
+
import type { TokenDTO } from '@explorins/pers-sdk/token';
|
|
13
|
+
|
|
14
|
+
// ChainData type - matches what Web3Manager.getChainDataById returns
|
|
15
|
+
type ChainData = Awaited<ReturnType<Web3Manager['getChainDataById']>>;
|
|
14
16
|
|
|
15
17
|
// Re-export for convenience
|
|
16
18
|
export type { AccountOwnedTokensResult } from '@explorins/pers-sdk/web3';
|
|
@@ -161,27 +163,40 @@ export const useWeb3 = () => {
|
|
|
161
163
|
}
|
|
162
164
|
}, [web3, isInitialized]);
|
|
163
165
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
+
/**
|
|
167
|
+
* Resolve IPFS URL to HTTP gateway URL
|
|
168
|
+
*
|
|
169
|
+
* @deprecated Use `sdk.tenant.resolveIPFSUrl()` directly - IPFS is chain-agnostic
|
|
170
|
+
* @param url - IPFS URL to resolve (ipfs://...)
|
|
171
|
+
* @returns Promise resolving to HTTP gateway URL
|
|
172
|
+
*/
|
|
173
|
+
const resolveIPFSUrl = useCallback(async (url: string): Promise<string> => {
|
|
174
|
+
if (!isInitialized || !sdk) {
|
|
166
175
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
try {
|
|
170
|
-
const result = await
|
|
179
|
+
const result = await sdk.tenants.resolveIPFSUrl(url);
|
|
171
180
|
return result;
|
|
172
181
|
} catch (error) {
|
|
173
182
|
console.error('Failed to resolve IPFS URL:', error);
|
|
174
183
|
throw error;
|
|
175
184
|
}
|
|
176
|
-
}, [
|
|
185
|
+
}, [sdk, isInitialized]);
|
|
177
186
|
|
|
178
|
-
|
|
187
|
+
/**
|
|
188
|
+
* Fetch and process token metadata from a URI
|
|
189
|
+
*
|
|
190
|
+
* @param tokenUri - Token URI to fetch metadata from
|
|
191
|
+
* @returns Promise resolving to processed metadata or null
|
|
192
|
+
*/
|
|
193
|
+
const fetchAndProcessMetadata = useCallback(async (tokenUri: string): Promise<TokenMetadata | null> => {
|
|
179
194
|
if (!isInitialized || !web3) {
|
|
180
195
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
181
196
|
}
|
|
182
197
|
|
|
183
198
|
try {
|
|
184
|
-
const result = await web3.fetchAndProcessMetadata(tokenUri
|
|
199
|
+
const result = await web3.fetchAndProcessMetadata(tokenUri);
|
|
185
200
|
return result;
|
|
186
201
|
} catch (error) {
|
|
187
202
|
console.error('Failed to fetch and process metadata:', error);
|
|
@@ -189,7 +204,7 @@ export const useWeb3 = () => {
|
|
|
189
204
|
}
|
|
190
205
|
}, [web3, isInitialized]);
|
|
191
206
|
|
|
192
|
-
const getChainDataById = useCallback(async (chainId: number): Promise<ChainData
|
|
207
|
+
const getChainDataById = useCallback(async (chainId: number): Promise<ChainData> => {
|
|
193
208
|
if (!isInitialized || !web3) {
|
|
194
209
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
195
210
|
}
|
|
@@ -255,7 +270,7 @@ export const useWeb3 = () => {
|
|
|
255
270
|
*
|
|
256
271
|
* @param accountAddress - Any valid blockchain address (wallet, contract, etc.)
|
|
257
272
|
* @param token - Token definition (from getRewardTokens, getStatusTokens, etc.)
|
|
258
|
-
* @param maxTokens - Maximum tokens to retrieve (default:
|
|
273
|
+
* @param maxTokens - Maximum tokens to retrieve (default: 100, max: 100)
|
|
259
274
|
* @returns Promise resolving to result with owned tokens
|
|
260
275
|
* @throws Error if SDK is not initialized
|
|
261
276
|
*
|
|
@@ -277,7 +292,7 @@ export const useWeb3 = () => {
|
|
|
277
292
|
const getAccountOwnedTokensFromContract = useCallback(async (
|
|
278
293
|
accountAddress: string,
|
|
279
294
|
token: TokenDTO,
|
|
280
|
-
maxTokens: number =
|
|
295
|
+
maxTokens: number = 100
|
|
281
296
|
): Promise<AccountOwnedTokensResult> => {
|
|
282
297
|
if (!isInitialized || !web3) {
|
|
283
298
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
@@ -295,13 +310,13 @@ export const useWeb3 = () => {
|
|
|
295
310
|
*
|
|
296
311
|
* @param accountAddress - Any valid blockchain address (wallet, contract, etc.)
|
|
297
312
|
* @param token - Token definition
|
|
298
|
-
* @param maxTokens - Maximum tokens to retrieve (default:
|
|
313
|
+
* @param maxTokens - Maximum tokens to retrieve (default: 100, max: 100)
|
|
299
314
|
* @returns TokenCollectionRequest ready for getTokenCollection()
|
|
300
315
|
*/
|
|
301
316
|
const buildCollectionRequest = useCallback((
|
|
302
317
|
accountAddress: string,
|
|
303
318
|
token: TokenDTO,
|
|
304
|
-
maxTokens: number =
|
|
319
|
+
maxTokens: number = 100
|
|
305
320
|
): TokenCollectionRequest => {
|
|
306
321
|
if (!web3) {
|
|
307
322
|
throw new Error('SDK not initialized. Call initialize() first.');
|
|
@@ -24,6 +24,15 @@ import type {
|
|
|
24
24
|
// Re-export PersConfig for external use
|
|
25
25
|
export type { PersConfig } from '@explorins/pers-sdk/core';
|
|
26
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Context interface for PERS SDK React Native integration
|
|
29
|
+
*
|
|
30
|
+
* @property sdk - Main SDK instance (null until initialized)
|
|
31
|
+
* @property authProvider - Platform-specific auth provider
|
|
32
|
+
* @property isInitialized - Whether SDK has been initialized
|
|
33
|
+
* @property isAuthenticated - Whether user is currently authenticated
|
|
34
|
+
* @property user - Current user data (null if not authenticated)
|
|
35
|
+
*/
|
|
27
36
|
export interface PersSDKContext {
|
|
28
37
|
// Main SDK instance
|
|
29
38
|
sdk: PersSDK | null;
|
|
@@ -46,7 +55,35 @@ export interface PersSDKContext {
|
|
|
46
55
|
// Create the context
|
|
47
56
|
const SDKContext = createContext<PersSDKContext | null>(null);
|
|
48
57
|
|
|
49
|
-
|
|
58
|
+
/**
|
|
59
|
+
* PERS SDK Provider for React Native
|
|
60
|
+
*
|
|
61
|
+
* Wraps your app to provide SDK context to all child components.
|
|
62
|
+
* Handles platform-specific initialization (DPoP, storage, etc.).
|
|
63
|
+
*
|
|
64
|
+
* @param config - SDK configuration (see PersConfig)
|
|
65
|
+
* @param config.apiProjectKey - Your PERS project key (required)
|
|
66
|
+
* @param config.environment - 'staging' | 'production' (default: 'staging')
|
|
67
|
+
* @param config.captureWalletEvents - Enable real-time blockchain events (default: true)
|
|
68
|
+
* @param config.dpop - DPoP configuration for enhanced security
|
|
69
|
+
*
|
|
70
|
+
* @example Basic usage
|
|
71
|
+
* ```tsx
|
|
72
|
+
* <PersSDKProvider config={{ apiProjectKey: 'my-project' }}>
|
|
73
|
+
* <App />
|
|
74
|
+
* </PersSDKProvider>
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example Disable wallet events
|
|
78
|
+
* ```tsx
|
|
79
|
+
* <PersSDKProvider config={{
|
|
80
|
+
* apiProjectKey: 'my-project',
|
|
81
|
+
* captureWalletEvents: false // Disable auto-connect to blockchain events
|
|
82
|
+
* }}>
|
|
83
|
+
* <App />
|
|
84
|
+
* </PersSDKProvider>
|
|
85
|
+
* ```
|
|
86
|
+
*/
|
|
50
87
|
export const PersSDKProvider: React.FC<{
|
|
51
88
|
children: ReactNode;
|
|
52
89
|
config?: PersConfig;
|