Skip to content

Latest commit

 

History

History
235 lines (172 loc) · 8.54 KB

File metadata and controls

235 lines (172 loc) · 8.54 KB

Global Patches and Polyfills Documentation

This document provides comprehensive documentation about global modifications, monkey patches, and polyfills implemented in the SVMSeek application for new contributors.

Overview

SVMSeek operates in a complex browser extension ecosystem where multiple wallet extensions compete for global properties and APIs. To ensure compatibility and prevent crashes, several global modifications have been implemented as defensive programming measures.

⚠️ IMPORTANT: All global patches can now be controlled via feature flags in src/utils/featureFlags.ts. This allows fine-grained control over which modifications are enabled in different environments.

🎛️ Feature Flag Control

Global patches are now controlled by environment variables and feature flags:

# Global patch control
REACT_APP_ENABLE_OS_POLYFILL=true
REACT_APP_ENABLE_BUFFER_POLYFILL=true
REACT_APP_ENABLE_SAFE_EVENT_LISTENERS=true
REACT_APP_ENABLE_CRYPTO_POLYFILL=true

# Security features (enabled by default)
REACT_APP_DISABLE_RATE_LIMITING=false
REACT_APP_DISABLE_ORIGIN_VALIDATION=false
REACT_APP_DISABLE_MESSAGE_SECURITY=false

# Extension compatibility (enabled by default)
REACT_APP_ENABLE_EXTENSION_COMPATIBILITY=true

Default Behavior:

  • Development: All patches enabled for maximum compatibility
  • Staging: Essential patches enabled
  • Production: Only explicitly enabled patches (safer defaults)

🚨 Critical Global Modifications

1. EventTarget.prototype.addEventListener (SafeEventListenerUtility)

Location: src/utils/SafeEventListenerUtility.ts Purpose: Prevents null property access crashes from third-party wallet extensions

What it does:

  • Wraps all event listeners with null-safety checks
  • Prevents "Cannot read properties of null" crashes
  • Validates message event data before passing to handlers

Why it's needed: Multiple wallet extensions assume event.data is always defined, causing app crashes when it's null. This protection layer ensures the app remains stable.

Impact:

  • All new event listeners get automatic null protection
  • Minimal performance overhead (only basic null checks)
  • Can be disabled via safeEventListenerUtility.disableSafeListeners()

Example crashes prevented:

// Before: Crashes with "Cannot read properties of null (reading 'type')"
window.addEventListener('message', (event) => {
  console.log(event.data.type); // CRASH if event.data is null
});

// After: Safe with automatic null checking
// The wrapper validates event.data before calling the handler

2. Object.defineProperty (Wallet Extension Conflicts)

Location: src/utils/globalErrorHandler.ts Purpose: Prevents "Cannot redefine property" errors from multiple wallet extensions

What it does:

  • Intercepts attempts to redefine window.ethereum
  • Allows the first extension to succeed, prevents subsequent conflicts
  • Logs conflicts for debugging without crashing the app

Why it's needed: When users have multiple wallet extensions (MetaMask, Phantom, etc.), each tries to define window.ethereum, causing "Cannot redefine property" errors that crash the entire application.

Impact:

  • First wallet extension to load defines window.ethereum
  • Subsequent extensions are blocked but logged
  • Application remains stable with multiple extensions

3. OS Module Polyfill

Location: src/polyfills/os-browser.js Purpose: Fixes "c.homedir is not a function" crashes in browser environments

What it does:

  • Provides browser-compatible implementations of Node.js os module functions
  • Handles both CommonJS and ES6 module imports
  • Prevents dependency loading crashes

Why it's needed: The @project-serum/anchor and @coral-xyz/anchor dependencies try to access require("os").homedir() in browser environments, causing immediate application crashes.

Impact:

  • Solana/Anchor dependencies load successfully in browser
  • No more "homedir is not a function" errors
  • Maintains compatibility with Node.js environments

📁 File Organization

Core Error Handling

  • src/utils/globalErrorHandler.ts - Main error handler with wallet conflict protection
  • src/utils/SafeEventListenerUtility.ts - Safe event listener wrapper utility
  • src/polyfills/os-browser.js - OS module polyfill for browser compatibility

Documentation

  • docs/ERROR_HANDLING.md - Detailed error handling patterns and recovery
  • GLOBAL_PATCHES.md - This document

Tests

  • src/services/__tests__/WalletInjectionService.test.ts - Security and safety testing
  • src/utils/__tests__/globalErrorHandler.test.ts - Error handler testing

🔧 Usage Guidelines

For New Developers

  1. Understanding the Need: These patches exist because SVMSeek operates in a "wild west" browser extension environment where multiple wallet extensions compete and conflict.

  2. When to Use:

    • Only when dealing with third-party extension compatibility
    • When crashes are caused by external libraries/extensions
    • As a last resort after other solutions fail
  3. Best Practices:

    • Always document the reason for any global modification
    • Provide disable/cleanup methods when possible
    • Use encapsulated utilities instead of direct monkey-patching
    • Test thoroughly with multiple wallet extensions

Disabling Patches (If Needed)

// Disable safe event listeners
import { safeEventListenerUtility } from './utils/SafeEventListenerUtility';
safeEventListenerUtility.disableSafeListeners();

// The wallet conflict protection is harder to disable safely
// as it needs to remain active to prevent crashes

🧪 Testing with Multiple Extensions

To test the effectiveness of these patches:

  1. Install multiple wallet extensions (MetaMask, Phantom, Solflare)
  2. Load the SVMSeek application
  3. Verify no "Cannot redefine property" errors in console
  4. Test wallet functionality with each extension
  5. Check that message events don't crash with null data

🚨 Security Considerations

EventTarget Modification

  • Only affects new event listeners (existing ones unchanged)
  • Adds validation overhead but improves stability
  • Cannot be exploited to bypass security (only adds safety)

Object.defineProperty Modification

  • Only monitors window.ethereum redefinition attempts
  • Does not intercept other property definitions
  • Maintains first-extension-wins security model

OS Module Polyfill

  • Provides minimal required functionality only
  • Does not expose sensitive system information
  • Maintains browser security boundaries

🔄 Recovery Events

The application dispatches custom events for error recovery:

// Listen for error recovery events
window.addEventListener('svmseek-error-recovery', (event) => {
  console.log('Error recovered:', event.detail);
});

// Listen for wallet conflict events
window.addEventListener('svmseek-wallet-conflict', (event) => {
  console.log('Wallet conflict:', event.detail);
});

📈 Performance Impact

EventTarget Wrapper

  • Overhead: ~1-2μs per event listener call
  • Memory: Minimal (one wrapper function per listener)
  • Scalability: Linear with number of event listeners

Object.defineProperty Wrapper

  • Overhead: ~0.5μs per property definition
  • Memory: Negligible
  • Scalability: Only affects property definitions on window

OS Polyfill

  • Load Time: ~1ms initial loading
  • Runtime: Zero (functions called rarely)
  • Bundle Size: ~2KB

🔮 Future Considerations

Potential Improvements

  1. Targeted Protection: Move from global patches to component-specific protection
  2. Extension Detection: Detect specific wallet extensions and apply targeted fixes
  3. Dynamic Loading: Only load patches when specific conflicts are detected
  4. Performance Monitoring: Add metrics to track patch effectiveness

Migration Strategy

As the browser extension ecosystem stabilizes, these patches can be gradually removed:

  1. Monitor crash reports for specific error patterns
  2. Test with latest extension versions for resolved conflicts
  3. Implement feature flags to disable patches conditionally
  4. Measure performance impact of removal

📞 Support

If you encounter issues related to these global modifications:

  1. Check browser console for error messages
  2. Verify which wallet extensions are installed
  3. Test with extensions disabled to isolate the issue
  4. Review the error recovery events for debugging information

For questions about these patches, consult:

  • The original implementation in git history
  • The detailed comments in the source files
  • The comprehensive test suites that validate the behavior