@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.
- package/README.md +276 -123
- package/dist/hooks/index.d.ts +8 -0
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +7 -0
- package/dist/hooks/useAnalytics.d.ts +96 -0
- package/dist/hooks/useAnalytics.d.ts.map +1 -0
- package/dist/hooks/useAnalytics.js +73 -0
- package/dist/hooks/useAuth.d.ts +52 -7
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +250 -3
- package/dist/hooks/useBusiness.d.ts +45 -3
- package/dist/hooks/useBusiness.d.ts.map +1 -1
- package/dist/hooks/useBusiness.js +182 -28
- package/dist/hooks/useCampaigns.d.ts +11 -4
- package/dist/hooks/useCampaigns.d.ts.map +1 -1
- package/dist/hooks/useCampaigns.js +101 -39
- package/dist/hooks/useDonations.d.ts +33 -0
- package/dist/hooks/useDonations.d.ts.map +1 -0
- package/dist/hooks/useDonations.js +62 -0
- package/dist/hooks/useFiles.d.ts +50 -0
- package/dist/hooks/useFiles.d.ts.map +1 -0
- package/dist/hooks/useFiles.js +140 -0
- package/dist/hooks/usePurchases.d.ts +9 -0
- package/dist/hooks/usePurchases.d.ts.map +1 -0
- package/dist/hooks/usePurchases.js +56 -0
- package/dist/hooks/useRedemptions.d.ts +10 -5
- package/dist/hooks/useRedemptions.d.ts.map +1 -1
- package/dist/hooks/useRedemptions.js +94 -66
- package/dist/hooks/useTenants.d.ts +10 -0
- package/dist/hooks/useTenants.d.ts.map +1 -0
- package/dist/hooks/useTenants.js +68 -0
- package/dist/hooks/useTokens.d.ts +36 -2
- package/dist/hooks/useTokens.d.ts.map +1 -1
- package/dist/hooks/useTokens.js +180 -19
- package/dist/hooks/useTransactions.d.ts +45 -3
- package/dist/hooks/useTransactions.d.ts.map +1 -1
- package/dist/hooks/useTransactions.js +152 -31
- package/dist/hooks/useUserStatus.d.ts +9 -0
- package/dist/hooks/useUserStatus.d.ts.map +1 -0
- package/dist/hooks/useUserStatus.js +57 -0
- package/dist/hooks/useUsers.d.ts +17 -0
- package/dist/hooks/useUsers.d.ts.map +1 -0
- package/dist/hooks/useUsers.js +120 -0
- package/dist/hooks/useWeb3.d.ts +69 -6
- package/dist/hooks/useWeb3.d.ts.map +1 -1
- package/dist/hooks/useWeb3.js +177 -17
- package/dist/index.d.ts +6 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12199 -796
- package/dist/index.js.map +1 -1
- package/dist/polyfills/index.d.ts +1 -1
- package/dist/polyfills/index.d.ts.map +1 -1
- package/dist/polyfills/index.js +155 -9
- package/dist/polyfills/web3-polyfills.d.ts +7 -0
- package/dist/polyfills/web3-polyfills.d.ts.map +1 -0
- package/dist/polyfills/web3-polyfills.js +85 -0
- package/dist/providers/PersSDKProvider.d.ts +28 -18
- package/dist/providers/PersSDKProvider.d.ts.map +1 -1
- package/dist/providers/PersSDKProvider.js +63 -129
- package/dist/providers/react-native-auth-provider.d.ts +19 -64
- package/dist/providers/react-native-auth-provider.d.ts.map +1 -1
- package/dist/providers/react-native-auth-provider.js +57 -175
- package/package.json +171 -157
- package/src/hooks/index.ts +11 -1
- package/src/hooks/useAnalytics.ts +150 -0
- package/src/hooks/useAuth.ts +286 -27
- package/src/hooks/useBusiness.ts +193 -30
- package/src/hooks/useCampaigns.ts +121 -43
- package/src/hooks/useDonations.ts +68 -0
- package/src/hooks/useFiles.ts +160 -0
- package/src/hooks/usePurchases.ts +69 -0
- package/src/hooks/useRedemptions.ts +109 -68
- package/src/hooks/useTenants.ts +77 -0
- package/src/hooks/useTokens.ts +189 -21
- package/src/hooks/useTransactions.ts +170 -34
- package/src/hooks/useUserStatus.ts +65 -0
- package/src/hooks/useUsers.ts +133 -0
- package/src/hooks/useWeb3.ts +201 -21
- package/src/index.ts +21 -17
- package/src/polyfills/index.ts +163 -10
- package/src/polyfills/web3-polyfills.ts +98 -0
- package/src/providers/PersSDKProvider.tsx +114 -178
- package/src/providers/react-native-auth-provider.ts +65 -208
- package/dist/index.esm.js +0 -1057
- package/dist/index.esm.js.map +0 -1
- package/dist/polyfills/index.simple.d.ts +0 -2
- package/dist/polyfills/index.simple.d.ts.map +0 -1
- package/dist/polyfills/index.simple.js +0 -17
- package/src/polyfills/index.simple.ts +0 -22
- package/src/types/external-modules.d.ts +0 -13
package/src/hooks/useWeb3.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
12
|
-
|
|
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
|
-
|
|
16
|
-
|
|
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.
|
|
21
|
-
console.log('
|
|
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('
|
|
141
|
+
console.error('Failed to fetch token metadata:', error);
|
|
25
142
|
throw error;
|
|
26
143
|
}
|
|
27
|
-
}, [
|
|
144
|
+
}, [sdk, isInitialized]);
|
|
28
145
|
|
|
29
|
-
const getTokenCollection = useCallback(async (request:
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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.
|
|
40
|
-
console.log('
|
|
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('
|
|
171
|
+
console.error('Failed to resolve IPFS URL:', error);
|
|
44
172
|
throw error;
|
|
45
173
|
}
|
|
46
|
-
}, [
|
|
174
|
+
}, [sdk, isInitialized]);
|
|
47
175
|
|
|
48
|
-
const
|
|
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
|
|
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
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
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';
|
package/src/polyfills/index.ts
CHANGED
|
@@ -1,16 +1,169 @@
|
|
|
1
|
-
//
|
|
2
|
-
//
|
|
1
|
+
// React Native polyfills for crypto and Web3 functionality
|
|
2
|
+
// Consolidated "batteries included" approach for React Native SDK
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
import { Buffer } from 'buffer';
|
|
5
|
+
import { setupWeb3InstanceofPolyfill } from './web3-polyfills';
|
|
6
|
+
|
|
7
|
+
// Initialize React Native polyfills
|
|
5
8
|
export const initializeReactNativePolyfills = (): boolean => {
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
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();
|