@explorins/pers-sdk-react-native 1.3.2 → 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/README.md +276 -123
  2. package/dist/hooks/index.d.ts +8 -0
  3. package/dist/hooks/index.d.ts.map +1 -1
  4. package/dist/hooks/index.js +7 -0
  5. package/dist/hooks/useAnalytics.d.ts +96 -0
  6. package/dist/hooks/useAnalytics.d.ts.map +1 -0
  7. package/dist/hooks/useAnalytics.js +73 -0
  8. package/dist/hooks/useAuth.d.ts +52 -7
  9. package/dist/hooks/useAuth.d.ts.map +1 -1
  10. package/dist/hooks/useAuth.js +250 -3
  11. package/dist/hooks/useBusiness.d.ts +45 -3
  12. package/dist/hooks/useBusiness.d.ts.map +1 -1
  13. package/dist/hooks/useBusiness.js +182 -28
  14. package/dist/hooks/useCampaigns.d.ts +11 -4
  15. package/dist/hooks/useCampaigns.d.ts.map +1 -1
  16. package/dist/hooks/useCampaigns.js +101 -39
  17. package/dist/hooks/useDonations.d.ts +33 -0
  18. package/dist/hooks/useDonations.d.ts.map +1 -0
  19. package/dist/hooks/useDonations.js +62 -0
  20. package/dist/hooks/useFiles.d.ts +50 -0
  21. package/dist/hooks/useFiles.d.ts.map +1 -0
  22. package/dist/hooks/useFiles.js +140 -0
  23. package/dist/hooks/usePurchases.d.ts +9 -0
  24. package/dist/hooks/usePurchases.d.ts.map +1 -0
  25. package/dist/hooks/usePurchases.js +56 -0
  26. package/dist/hooks/useRedemptions.d.ts +10 -5
  27. package/dist/hooks/useRedemptions.d.ts.map +1 -1
  28. package/dist/hooks/useRedemptions.js +94 -66
  29. package/dist/hooks/useTenants.d.ts +10 -0
  30. package/dist/hooks/useTenants.d.ts.map +1 -0
  31. package/dist/hooks/useTenants.js +68 -0
  32. package/dist/hooks/useTokens.d.ts +36 -2
  33. package/dist/hooks/useTokens.d.ts.map +1 -1
  34. package/dist/hooks/useTokens.js +180 -19
  35. package/dist/hooks/useTransactions.d.ts +45 -3
  36. package/dist/hooks/useTransactions.d.ts.map +1 -1
  37. package/dist/hooks/useTransactions.js +152 -31
  38. package/dist/hooks/useUserStatus.d.ts +9 -0
  39. package/dist/hooks/useUserStatus.d.ts.map +1 -0
  40. package/dist/hooks/useUserStatus.js +57 -0
  41. package/dist/hooks/useUsers.d.ts +17 -0
  42. package/dist/hooks/useUsers.d.ts.map +1 -0
  43. package/dist/hooks/useUsers.js +120 -0
  44. package/dist/hooks/useWeb3.d.ts +69 -6
  45. package/dist/hooks/useWeb3.d.ts.map +1 -1
  46. package/dist/hooks/useWeb3.js +177 -17
  47. package/dist/index.d.ts +6 -4
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +12199 -796
  50. package/dist/index.js.map +1 -1
  51. package/dist/polyfills/index.d.ts +1 -1
  52. package/dist/polyfills/index.d.ts.map +1 -1
  53. package/dist/polyfills/index.js +155 -9
  54. package/dist/polyfills/web3-polyfills.d.ts +7 -0
  55. package/dist/polyfills/web3-polyfills.d.ts.map +1 -0
  56. package/dist/polyfills/web3-polyfills.js +85 -0
  57. package/dist/providers/PersSDKProvider.d.ts +28 -18
  58. package/dist/providers/PersSDKProvider.d.ts.map +1 -1
  59. package/dist/providers/PersSDKProvider.js +63 -129
  60. package/dist/providers/react-native-auth-provider.d.ts +19 -64
  61. package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
  62. package/dist/providers/react-native-auth-provider.js +57 -175
  63. package/package.json +171 -157
  64. package/src/hooks/index.ts +11 -1
  65. package/src/hooks/useAnalytics.ts +150 -0
  66. package/src/hooks/useAuth.ts +286 -27
  67. package/src/hooks/useBusiness.ts +193 -30
  68. package/src/hooks/useCampaigns.ts +121 -43
  69. package/src/hooks/useDonations.ts +68 -0
  70. package/src/hooks/useFiles.ts +160 -0
  71. package/src/hooks/usePurchases.ts +69 -0
  72. package/src/hooks/useRedemptions.ts +109 -68
  73. package/src/hooks/useTenants.ts +77 -0
  74. package/src/hooks/useTokens.ts +189 -21
  75. package/src/hooks/useTransactions.ts +170 -34
  76. package/src/hooks/useUserStatus.ts +65 -0
  77. package/src/hooks/useUsers.ts +133 -0
  78. package/src/hooks/useWeb3.ts +201 -21
  79. package/src/index.ts +21 -17
  80. package/src/polyfills/index.ts +163 -10
  81. package/src/polyfills/web3-polyfills.ts +98 -0
  82. package/src/providers/PersSDKProvider.tsx +114 -178
  83. package/src/providers/react-native-auth-provider.ts +65 -208
  84. package/dist/index.esm.js +0 -1057
  85. package/dist/index.esm.js.map +0 -1
  86. package/dist/polyfills/index.simple.d.ts +0 -2
  87. package/dist/polyfills/index.simple.d.ts.map +0 -1
  88. package/dist/polyfills/index.simple.js +0 -17
  89. package/src/polyfills/index.simple.ts +0 -22
  90. package/src/types/external-modules.d.ts +0 -13
@@ -1,51 +1,224 @@
1
1
  import { useCallback } from 'react';
2
2
  import { usePersSDK } from '../providers/PersSDKProvider';
3
+ import type {
4
+ TokenBalance,
5
+ TokenBalanceRequest,
6
+ TokenCollectionRequest,
7
+ TokenCollection,
8
+ TokenMetadata
9
+ } from '@explorins/pers-sdk/web3';
10
+ import type { ChainData } from '@explorins/pers-sdk/web3-chain';
3
11
 
12
+ interface WalletInfo {
13
+ address: string | null;
14
+ isConnected: boolean;
15
+ }
16
+
17
+ /**
18
+ * React hook for Web3 operations in the PERS SDK
19
+ *
20
+ * Provides comprehensive Web3 functionality including token balance queries,
21
+ * metadata retrieval, collection management, IPFS resolution, and blockchain
22
+ * explorer integration. Supports multi-chain operations and wallet management.
23
+ *
24
+ * @returns Web3 hook with methods for blockchain operations
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * function Web3Component() {
29
+ * const {
30
+ * getTokenBalance,
31
+ * getTokenMetadata,
32
+ * getWalletInfo,
33
+ * accountAddress
34
+ * } = useWeb3();
35
+ *
36
+ * const loadTokenData = async () => {
37
+ * try {
38
+ * if (!accountAddress) {
39
+ * console.log('No wallet connected');
40
+ * return;
41
+ * }
42
+ *
43
+ * const balance = await getTokenBalance({
44
+ * walletAddress: accountAddress,
45
+ * contractAddress: '0x123...',
46
+ * chainId: 1
47
+ * });
48
+ *
49
+ * console.log('Token balance:', balance);
50
+ * } catch (error) {
51
+ * console.error('Failed to load token data:', error);
52
+ * }
53
+ * };
54
+ *
55
+ * return (
56
+ * <div>
57
+ * {accountAddress ? (
58
+ * <div>
59
+ * <p>Wallet: {accountAddress}</p>
60
+ * <button onClick={loadTokenData}>Load Tokens</button>
61
+ * </div>
62
+ * ) : (
63
+ * <p>No wallet connected</p>
64
+ * )}
65
+ * </div>
66
+ * );
67
+ * }
68
+ * ```
69
+ */
4
70
  export const useWeb3 = () => {
5
- const { web3, isInitialized, isAuthenticated, accountAddress } = usePersSDK();
71
+ const { sdk, isInitialized, isAuthenticated, accountAddress } = usePersSDK();
6
72
 
7
73
  if (!isAuthenticated && isInitialized) {
8
74
  console.warn('SDK not authenticated. Some web3 operations may fail.');
9
75
  }
10
76
 
11
- const getTokenBalance = useCallback(async (request: any) => {
12
- if (!isInitialized) {
77
+ /**
78
+ * Retrieves token balance for a specific wallet and contract
79
+ *
80
+ * @param request - Token balance request containing wallet address, contract, and chain info
81
+ * @returns Promise resolving to token balance data
82
+ * @throws Error if SDK is not initialized
83
+ *
84
+ * @example
85
+ * ```typescript
86
+ * const { getTokenBalance } = useWeb3();
87
+ * const balance = await getTokenBalance({
88
+ * walletAddress: '0x123...',
89
+ * contractAddress: '0x456...',
90
+ * chainId: 1,
91
+ * tokenId: '1' // For NFTs
92
+ * });
93
+ * console.log('Balance:', balance.balance);
94
+ * ```
95
+ */
96
+ const getTokenBalance = useCallback(async (request: TokenBalanceRequest): Promise<TokenBalance> => {
97
+ console.log('[useWeb3] getTokenBalance called with request:', request);
98
+ if (!isInitialized || !sdk) {
13
99
  throw new Error('SDK not initialized. Call initialize() first.');
14
100
  }
15
- if (!web3?.getTokenBalance) {
16
- throw new Error('getTokenBalance method not available');
101
+
102
+ try {
103
+ const result = await sdk.web3.getTokenBalance(request);
104
+ console.log('Token balance fetched successfully:', result);
105
+ return result;
106
+ } catch (error) {
107
+ console.error('Failed to fetch token balance:', error);
108
+ throw error;
109
+ }
110
+ }, [sdk, isInitialized]);
111
+
112
+ /**
113
+ * Retrieves metadata for a specific token (useful for NFTs)
114
+ *
115
+ * @param request - Token balance request containing contract and token info
116
+ * @returns Promise resolving to token metadata or null if not available
117
+ * @throws Error if SDK is not initialized
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * const { getTokenMetadata } = useWeb3();
122
+ * const metadata = await getTokenMetadata({
123
+ * contractAddress: '0x123...',
124
+ * tokenId: '1',
125
+ * chainId: 1
126
+ * });
127
+ * console.log('NFT name:', metadata?.name);
128
+ * console.log('NFT image:', metadata?.image);
129
+ * ```
130
+ */
131
+ const getTokenMetadata = useCallback(async (request: TokenBalanceRequest): Promise<TokenMetadata | null> => {
132
+ if (!isInitialized || !sdk) {
133
+ throw new Error('SDK not initialized. Call initialize() first.');
17
134
  }
18
135
 
19
136
  try {
20
- const result = await web3.getTokenBalance(request);
21
- console.log('Token balance fetched successfully:', result);
137
+ const result = await sdk.web3.getTokenMetadata(request);
138
+ console.log('Token metadata fetched successfully:', result);
22
139
  return result;
23
140
  } catch (error) {
24
- console.error('Failed to fetch token balance:', error);
141
+ console.error('Failed to fetch token metadata:', error);
25
142
  throw error;
26
143
  }
27
- }, [web3]);
144
+ }, [sdk, isInitialized]);
28
145
 
29
- const getTokenCollection = useCallback(async (request: any) => {
30
- if (!isInitialized) {
146
+ const getTokenCollection = useCallback(async (request: TokenCollectionRequest): Promise<TokenCollection> => {
147
+ if (!isInitialized || !sdk) {
31
148
  throw new Error('SDK not initialized. Call initialize() first.');
32
149
  }
33
- if (!web3?.getTokenCollection) {
34
- console.warn('getTokenCollection method not available');
35
- return [];
150
+
151
+ try {
152
+ const result = await sdk.web3.getTokenCollection(request);
153
+ console.log('Token collection fetched successfully:', result);
154
+ return result;
155
+ } catch (error) {
156
+ console.error('Failed to fetch token collection:', error);
157
+ throw error;
158
+ }
159
+ }, [sdk, isInitialized]);
160
+
161
+ const resolveIPFSUrl = useCallback(async (url: string, chainId: number): Promise<string> => {
162
+ if (!isInitialized || !sdk) {
163
+ throw new Error('SDK not initialized. Call initialize() first.');
36
164
  }
37
165
 
38
166
  try {
39
- const result = await web3.getTokenCollection(request);
40
- console.log(' Token collection fetched successfully:', result);
167
+ const result = await sdk.web3.resolveIPFSUrl(url, chainId);
168
+ console.log('IPFS URL resolved successfully:', result);
41
169
  return result;
42
170
  } catch (error) {
43
- console.error('Failed to fetch token collection:', error);
171
+ console.error('Failed to resolve IPFS URL:', error);
44
172
  throw error;
45
173
  }
46
- }, [web3]);
174
+ }, [sdk, isInitialized]);
47
175
 
48
- const getWalletInfo = useCallback(async () => {
176
+ const fetchAndProcessMetadata = useCallback(async (tokenUri: string, chainId: number): Promise<TokenMetadata | null> => {
177
+ if (!isInitialized || !sdk) {
178
+ throw new Error('SDK not initialized. Call initialize() first.');
179
+ }
180
+
181
+ try {
182
+ const result = await sdk.web3.fetchAndProcessMetadata(tokenUri, chainId);
183
+ console.log('Metadata fetched and processed successfully:', result);
184
+ return result;
185
+ } catch (error) {
186
+ console.error('Failed to fetch and process metadata:', error);
187
+ throw error;
188
+ }
189
+ }, [sdk, isInitialized]);
190
+
191
+ const getChainDataById = useCallback(async (chainId: number): Promise<ChainData | null> => {
192
+ if (!isInitialized || !sdk) {
193
+ throw new Error('SDK not initialized. Call initialize() first.');
194
+ }
195
+
196
+ try {
197
+ const result = await sdk.web3.getChainDataById(chainId);
198
+ console.log('Chain data fetched successfully:', result);
199
+ return result;
200
+ } catch (error) {
201
+ console.error('Failed to fetch chain data:', error);
202
+ throw error;
203
+ }
204
+ }, [sdk, isInitialized]);
205
+
206
+ const getExplorerUrl = useCallback(async (chainId: number, address: string, type: 'address' | 'tx'): Promise<string> => {
207
+ if (!isInitialized || !sdk) {
208
+ throw new Error('SDK not initialized. Call initialize() first.');
209
+ }
210
+
211
+ try {
212
+ const result = await sdk.web3.getExplorerUrl(chainId, address, type);
213
+ console.log('Explorer URL generated successfully:', result);
214
+ return result;
215
+ } catch (error) {
216
+ console.error('Failed to generate explorer URL:', error);
217
+ throw error;
218
+ }
219
+ }, [sdk, isInitialized]);
220
+
221
+ const getWalletInfo = useCallback(async (): Promise<WalletInfo | null> => {
49
222
  if (!isInitialized) {
50
223
  throw new Error('SDK not initialized. Call initialize() first.');
51
224
  }
@@ -62,9 +235,16 @@ export const useWeb3 = () => {
62
235
 
63
236
  return {
64
237
  getTokenBalance,
238
+ getTokenMetadata,
65
239
  getTokenCollection,
240
+ resolveIPFSUrl,
241
+ fetchAndProcessMetadata,
242
+ getChainDataById,
243
+ getExplorerUrl,
66
244
  getWalletInfo,
67
245
  accountAddress: isInitialized ? accountAddress : null,
68
- isAvailable: isInitialized && !!web3,
246
+ isAvailable: isInitialized && !!sdk?.web3,
69
247
  };
70
- };
248
+ };
249
+
250
+ export type Web3Hook = ReturnType<typeof useWeb3>;
package/src/index.ts CHANGED
@@ -1,25 +1,17 @@
1
1
  // Initialize React Native polyfills automatically
2
2
  import './polyfills';
3
3
 
4
- // TEMPORARY: Minimal exports to isolate the .from() error
5
- console.log('🔍 [DEBUG] Loading React Native SDK...');
6
-
7
4
  // Export React Native specific providers (FIRST - break circular dependency)
8
5
  export {
9
- BaseReactNativeAuthProvider,
10
6
  ReactNativeAuthProvider,
11
- SecureReactNativeAuthProvider,
12
- StorageStrategy,
13
7
  type ReactNativeAuthConfig
14
8
  } from './providers/react-native-auth-provider';
15
9
 
16
- console.log('🔍 [DEBUG] Auth providers loaded successfully');
17
-
18
10
  // Export Provider and Context directly (avoid circular import through hooks)
19
11
  export {
20
12
  PersSDKProvider,
21
13
  usePersSDK,
22
- type PersSDKConfig,
14
+ type PersConfig,
23
15
  type PersSDKContext
24
16
  } from './providers/PersSDKProvider';
25
17
 
@@ -31,21 +23,33 @@ export {
31
23
  useBusiness,
32
24
  useCampaigns,
33
25
  useRedemptions,
34
- useWeb3
26
+ useWeb3,
27
+ usePurchases,
28
+ useTenants,
29
+ useUsers,
30
+ useUserStatus,
31
+ useFiles,
32
+ useAnalytics,
33
+ useDonations
35
34
  } from './hooks';
36
35
 
37
- console.log('🔍 [DEBUG] React Native SDK loaded with full exports including useWeb3');
38
-
39
36
  export {
40
37
  ReactNativeHttpClient
41
38
  } from './providers/react-native-http-client';
42
39
 
43
40
  // Export polyfill utilities for advanced usage
44
41
  export {
45
- initializeReactNativePolyfills,
46
- isReactNative
42
+ initializeReactNativePolyfills
47
43
  } from './polyfills';
48
44
 
49
- // Note: For types and DTOs, import directly from @explorins/pers-shared
50
- // This maintains clean separation and avoids circular dependencies
51
- // Example: import { TokenDTO, BusinessDTO } from '@explorins/pers-shared';
45
+ // Re-export all types and utilities from @explorins/pers-shared
46
+ export * from '@explorins/pers-shared';
47
+
48
+ // Re-export Web3 types from base SDK
49
+ export type {
50
+ TokenBalanceRequest,
51
+ TokenBalance,
52
+ TokenMetadata,
53
+ TokenCollection,
54
+ TokenCollectionRequest
55
+ } from '@explorins/pers-sdk/web3';
@@ -1,16 +1,169 @@
1
- // Minimal React Native environment setup
2
- // No polyfills needed - modules are disabled at Metro level
1
+ // React Native polyfills for crypto and Web3 functionality
2
+ // Consolidated "batteries included" approach for React Native SDK
3
3
 
4
- // Simple initialization function for compatibility
4
+ import { Buffer } from 'buffer';
5
+ import { setupWeb3InstanceofPolyfill } from './web3-polyfills';
6
+
7
+ // Initialize React Native polyfills
5
8
  export const initializeReactNativePolyfills = (): boolean => {
6
- console.log('✅ [PERS SDK] React Native environment ready (no polyfills needed)');
7
- return true;
9
+ try {
10
+ // Set up basic global environment
11
+ (global as any).global = global;
12
+ (global as any).Buffer = Buffer;
13
+
14
+ // Add process if missing
15
+ if (typeof global !== 'undefined' && !global.process) {
16
+ global.process = {
17
+ env: {},
18
+ version: '16.0.0',
19
+ nextTick: (callback: () => void) => setTimeout(callback, 0)
20
+ } as any;
21
+ }
22
+
23
+ // Initialize crypto polyfills (CRITICAL for Web3)
24
+ require('react-native-get-random-values');
25
+
26
+ // Crypto polyfill for better Web3 compatibility
27
+ if (typeof global !== 'undefined' && !(global as any).crypto) {
28
+ (global as any).crypto = {
29
+ getRandomValues: (arr: any) => {
30
+ require('react-native-get-random-values');
31
+ return (global as any).crypto.getRandomValues(arr);
32
+ },
33
+ randomUUID: () => {
34
+ const hex = '0123456789abcdef';
35
+ let result = '';
36
+ for (let i = 0; i < 32; i++) {
37
+ result += hex[Math.floor(Math.random() * 16)];
38
+ if (i === 7 || i === 11 || i === 15 || i === 19) result += '-';
39
+ }
40
+ return result;
41
+ }
42
+ };
43
+ }
44
+
45
+ // Add URL polyfill for Web3 compatibility
46
+ if (typeof global !== 'undefined' && !(global as any).URL) {
47
+ try {
48
+ // Try to use react-native-url-polyfill if available
49
+ require('react-native-url-polyfill/auto');
50
+ } catch {
51
+ // Fallback to basic URL implementation
52
+ (global as any).URL = class URL {
53
+ constructor(public href: string) {}
54
+ toString() { return this.href; }
55
+ } as any;
56
+ }
57
+ }
58
+
59
+ // Add btoa/atob polyfills for Web3 compatibility
60
+ if (typeof global !== 'undefined') {
61
+ if (!(global as any).btoa) {
62
+ (global as any).btoa = (str: string) => Buffer.from(str, 'binary').toString('base64');
63
+ }
64
+ if (!(global as any).atob) {
65
+ (global as any).atob = (str: string) => Buffer.from(str, 'base64').toString('binary');
66
+ }
67
+ }
68
+
69
+ // EventTarget polyfill for Web3 providers
70
+ if (typeof global !== 'undefined' && !(global as any).EventTarget) {
71
+ (global as any).EventTarget = class EventTarget {
72
+ private listeners: { [key: string]: ((...args: any[]) => void)[] } = {};
73
+
74
+ addEventListener(type: string, listener: (...args: any[]) => void) {
75
+ if (!this.listeners[type]) {
76
+ this.listeners[type] = [];
77
+ }
78
+ this.listeners[type].push(listener);
79
+ }
80
+
81
+ removeEventListener(type: string, listener: (...args: any[]) => void) {
82
+ if (this.listeners[type]) {
83
+ const index = this.listeners[type].indexOf(listener);
84
+ if (index > -1) {
85
+ this.listeners[type].splice(index, 1);
86
+ }
87
+ }
88
+ }
89
+
90
+ dispatchEvent(event: any) {
91
+ if (this.listeners[event.type]) {
92
+ this.listeners[event.type].forEach(listener => {
93
+ listener(event);
94
+ });
95
+ }
96
+ return true;
97
+ }
98
+ };
99
+ }
100
+
101
+ // Performance polyfill
102
+ if (typeof global !== 'undefined' && !(global as any).performance) {
103
+ (global as any).performance = {
104
+ now: () => Date.now(),
105
+ timeOrigin: Date.now()
106
+ };
107
+ }
108
+
109
+ // Stream polyfill (minimal)
110
+ if (typeof global !== 'undefined' && !(global as any).stream) {
111
+ (global as any).stream = {
112
+ Readable: class {},
113
+ Writable: class {},
114
+ Transform: class {}
115
+ };
116
+ }
117
+
118
+ // Web3 specific polyfills for instanceof issues
119
+ setupWeb3Polyfills();
120
+ setupWeb3InstanceofPolyfill();
121
+
122
+ return true;
123
+ } catch (error) {
124
+ console.warn('[PERS SDK] Failed to initialize some polyfills:', error);
125
+ return true;
126
+ }
8
127
  };
9
128
 
10
- // Platform detection
11
- export const isReactNative = (): boolean => {
12
- return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
129
+ // Web3 specific polyfills to fix instanceof issues
130
+ const setupWeb3Polyfills = () => {
131
+ try {
132
+ // Ensure Symbol polyfill for constructor comparison
133
+ if (typeof global !== 'undefined' && !(global as any).Symbol) {
134
+ (global as any).Symbol = {
135
+ for: (key: string) => `Symbol(${key})`,
136
+ iterator: '@@iterator',
137
+ toStringTag: '@@toStringTag'
138
+ };
139
+ }
140
+
141
+ // Add constructor.name polyfill for better class detection
142
+ if (typeof global !== 'undefined' && typeof Function !== 'undefined') {
143
+ const originalToString = Function.prototype.toString;
144
+ if (!Function.prototype.name) {
145
+ Object.defineProperty(Function.prototype, 'name', {
146
+ get: function() {
147
+ const match = originalToString.call(this).match(/function\s*([^(]*)/);
148
+ return match ? match[1] : '';
149
+ }
150
+ });
151
+ }
152
+ }
153
+
154
+ // Module resolution enhancement for Web3
155
+ if (typeof global !== 'undefined') {
156
+ // Store reference to help with instanceof checks
157
+ (global as any).__PERS_SDK_WEB3_POLYFILLS__ = true;
158
+ }
159
+
160
+ } catch (error) {
161
+ console.warn('[PERS SDK] Web3 polyfills setup failed:', error);
162
+ }
13
163
  };
14
164
 
15
- // Auto-initialize
16
- initializeReactNativePolyfills();
165
+ // Auto-initialize polyfills when SDK is imported
166
+ initializeReactNativePolyfills();
167
+
168
+ // Export utilities for advanced usage
169
+ export { createSafeWeb3Check } from './web3-polyfills';
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Web3 specific polyfills for React Native
3
+ * Addresses instanceof and constructor issues in React Native environments
4
+ */
5
+
6
+ export const setupWeb3InstanceofPolyfill = () => {
7
+ try {
8
+ // Store the original instanceof behavior
9
+ const originalInstanceof = Function.prototype[Symbol.hasInstance];
10
+
11
+ // Override Symbol.hasInstance for better Web3 detection in React Native
12
+ if (typeof global !== 'undefined' && global.Symbol && global.Symbol.hasInstance) {
13
+ // Create a safer instanceof check for Web3
14
+ const createSafeInstanceofCheck = (constructor: any) => {
15
+ return function(instance: any) {
16
+ // Try the original check first
17
+ try {
18
+ if (originalInstanceof) {
19
+ return originalInstanceof.call(constructor, instance);
20
+ }
21
+ return instance instanceof constructor;
22
+ } catch (error) {
23
+ // Fallback to constructor and duck-typing checks
24
+ if (!instance || typeof instance !== 'object') {
25
+ return false;
26
+ }
27
+
28
+ // Check constructor name
29
+ if (instance.constructor && instance.constructor.name === constructor.name) {
30
+ return true;
31
+ }
32
+
33
+ // Check constructor reference
34
+ if (instance.constructor === constructor) {
35
+ return true;
36
+ }
37
+
38
+ // For Web3 specifically, check characteristic properties
39
+ if (constructor.name === 'Web3' &&
40
+ 'currentProvider' in instance &&
41
+ 'eth' in instance &&
42
+ 'utils' in instance) {
43
+ return true;
44
+ }
45
+
46
+ return false;
47
+ }
48
+ };
49
+ };
50
+
51
+ // Apply the polyfill to global scope for dynamic loading
52
+ (global as any).__PERS_SDK_SAFE_INSTANCEOF__ = createSafeInstanceofCheck;
53
+
54
+ }
55
+
56
+ return true;
57
+ } catch (error) {
58
+ console.warn('[PERS SDK] Web3 instanceof polyfill setup failed:', error);
59
+ return false;
60
+ }
61
+ };
62
+
63
+ export const createSafeWeb3Check = (provider: unknown): boolean => {
64
+ if (!provider || typeof provider !== 'object') {
65
+ return false;
66
+ }
67
+
68
+ try {
69
+ // Method 1: Check if it's already a Web3 instance using multiple approaches
70
+ const providerObj = provider as any;
71
+
72
+ // Constructor name check
73
+ if (providerObj.constructor?.name === 'Web3') {
74
+ return true;
75
+ }
76
+
77
+ // Duck typing for Web3 properties
78
+ if ('currentProvider' in providerObj &&
79
+ 'eth' in providerObj &&
80
+ 'utils' in providerObj &&
81
+ typeof providerObj.eth === 'object') {
82
+ return true;
83
+ }
84
+
85
+ // Check for Web3 version property
86
+ if ('version' in providerObj && typeof providerObj.version === 'string') {
87
+ return true;
88
+ }
89
+
90
+ return false;
91
+ } catch (error) {
92
+ console.warn('Safe Web3 check failed:', error);
93
+ return false;
94
+ }
95
+ };
96
+
97
+ // Auto-initialize
98
+ setupWeb3InstanceofPolyfill();