// React Native polyfills for crypto and Web3 functionality // Consolidated "batteries included" approach for React Native SDK // CRITICAL: URL polyfill must be imported FIRST before any other code // This provides full URLSearchParams support for React Native import 'react-native-url-polyfill/auto'; import { Buffer } from 'buffer'; import { setupWeb3InstanceofPolyfill } from './web3-polyfills'; // Initialize React Native polyfills export const initializeReactNativePolyfills = (): boolean => { try { // Set up basic global environment (global as any).global = global; (global as any).Buffer = Buffer; // Add process if missing if (typeof global !== 'undefined' && !global.process) { global.process = { env: {}, version: '16.0.0', nextTick: (callback: () => void) => setTimeout(callback, 0) } as any; } // Initialize crypto polyfills (CRITICAL for Web3) require('react-native-get-random-values'); // Crypto polyfill for better Web3 compatibility if (typeof global !== 'undefined' && !(global as any).crypto) { (global as any).crypto = { getRandomValues: (arr: any) => { require('react-native-get-random-values'); return (global as any).crypto.getRandomValues(arr); }, randomUUID: () => { const hex = '0123456789abcdef'; let result = ''; for (let i = 0; i < 32; i++) { result += hex[Math.floor(Math.random() * 16)]; if (i === 7 || i === 11 || i === 15 || i === 19) result += '-'; } return result; } }; } // URL polyfill is handled by react-native-url-polyfill/auto import at top // Add btoa/atob polyfills for Web3 compatibility if (typeof global !== 'undefined') { if (!(global as any).btoa) { (global as any).btoa = (str: string) => Buffer.from(str, 'binary').toString('base64'); } if (!(global as any).atob) { (global as any).atob = (str: string) => Buffer.from(str, 'base64').toString('binary'); } } // EventTarget polyfill for Web3 providers if (typeof global !== 'undefined' && !(global as any).EventTarget) { (global as any).EventTarget = class EventTarget { private listeners: { [key: string]: ((...args: any[]) => void)[] } = {}; addEventListener(type: string, listener: (...args: any[]) => void) { if (!this.listeners[type]) { this.listeners[type] = []; } this.listeners[type].push(listener); } removeEventListener(type: string, listener: (...args: any[]) => void) { if (this.listeners[type]) { const index = this.listeners[type].indexOf(listener); if (index > -1) { this.listeners[type].splice(index, 1); } } } dispatchEvent(event: any) { if (this.listeners[event.type]) { this.listeners[event.type].forEach(listener => { listener(event); }); } return true; } }; } // Performance polyfill if (typeof global !== 'undefined' && !(global as any).performance) { (global as any).performance = { now: () => Date.now(), timeOrigin: Date.now() }; } // Stream polyfill (minimal) if (typeof global !== 'undefined' && !(global as any).stream) { (global as any).stream = { Readable: class {}, Writable: class {}, Transform: class {} }; } // Web3 specific polyfills for instanceof issues setupWeb3Polyfills(); setupWeb3InstanceofPolyfill(); return true; } catch (error) { console.warn('[PERS SDK] Failed to initialize some polyfills:', error); return true; } }; // Web3 specific polyfills to fix instanceof issues const setupWeb3Polyfills = () => { try { // Ensure Symbol polyfill for constructor comparison if (typeof global !== 'undefined' && !(global as any).Symbol) { (global as any).Symbol = { for: (key: string) => `Symbol(${key})`, iterator: '@@iterator', toStringTag: '@@toStringTag' }; } // Add constructor.name polyfill for better class detection if (typeof global !== 'undefined' && typeof Function !== 'undefined') { const originalToString = Function.prototype.toString; if (!Function.prototype.name) { Object.defineProperty(Function.prototype, 'name', { get: function() { const match = originalToString.call(this).match(/function\s*([^(]*)/); return match ? match[1] : ''; } }); } } // Module resolution enhancement for Web3 if (typeof global !== 'undefined') { // Store reference to help with instanceof checks (global as any).__PERS_SDK_WEB3_POLYFILLS__ = true; } } catch (error) { console.warn('[PERS SDK] Web3 polyfills setup failed:', error); } }; // Auto-initialize polyfills when SDK is imported initializeReactNativePolyfills(); // Export utilities for advanced usage export { createSafeWeb3Check } from './web3-polyfills';